python/cpython · error · OSError

getaddrinfo() returned empty list

Error message

getaddrinfo() returned empty list

What it means

Raised as OSError by create_connection when getaddrinfo() for the target (host, port) returns an empty list. Normally getaddrinfo raises on failure, but with certain flag combinations or AI_ADDRCONFIG-style behavior it can succeed with zero results; asyncio then has no address to connect to and raises this.

Source

Thrown at Lib/asyncio/base_events.py:1129

                'ssl_shutdown_timeout is only meaningful with ssl')

        if sock is not None:
            _check_ssl_socket(sock)

        if happy_eyeballs_delay is not None and interleave is None:
            # If using happy eyeballs, default to interleave addresses by family
            interleave = 1

        if host is not None or port is not None:
            if sock is not None:
                raise ValueError(
                    'host/port and sock can not be specified at the same time')

            infos = await self._ensure_resolved(
                (host, port), family=family,
                type=socket.SOCK_STREAM, proto=proto, flags=flags, loop=self)
            if not infos:
                raise OSError('getaddrinfo() returned empty list')

            if local_addr is not None:
                laddr_infos = await self._ensure_resolved(
                    local_addr, family=family,
                    type=socket.SOCK_STREAM, proto=proto,
                    flags=flags, loop=self)
                if not laddr_infos:
                    raise OSError('getaddrinfo() returned empty list')
            else:
                laddr_infos = None

            if interleave:
                infos = _interleave_addrinfos(infos, interleave)

            exceptions = []
            if happy_eyeballs_delay is None:
                # not using happy eyeballs
                for addrinfo in infos:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Verify the host resolves at all: socket.getaddrinfo(host, port, type=SOCK_STREAM) in a REPL.
  2. Drop custom flags and let asyncio use its defaults.
  3. Check the host string for typos/scheme prefixes like 'https://example.com' passed as a bare host.

Example fix

// before
await loop.create_connection(proto, 'https://example.com', 443)  # scheme left in host

// after
await loop.create_connection(proto, 'example.com', 443)
Defensive patterns

Strategy: validation

Validate before calling

import socket
infos = socket.getaddrinfo(host, port, type=socket.SOCK_STREAM)
assert infos, f'{host!r} resolves to nothing for SOCK_STREAM'

Try / catch

try:
    tp, pr = await loop.create_connection(proto, host, port)
except OSError as e:
    if 'returned empty list' not in str(e):
        raise
    host = host.removeprefix('https://').removeprefix('http://').split('/')[0]
    tp, pr = await loop.create_connection(proto, host, port)

Prevention

When it happens

Trigger: loop.create_connection(proto, host, port, flags=...) where the flags filter out all results (e.g. AI_ADDRCONFIG on a host family the machine lacks), or a resolver edge case returning [] for the requested family/type/proto combination.

Common situations: Passing custom flags copied from sync socket code; hosts whose only records are in a family the local machine cannot use (IPv6-only names on IPv4-only hosts with filtering resolvers); unusual NSS/resolver configurations in containers.

Understand the failure class

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/9b0a8c9e234bbeb2. Report an issue: GitHub.