python/cpython · error · OSError

getaddrinfo({host!r}) returned empty list

Error message

getaddrinfo({host!r}) returned empty list

What it means

Raised by BaseEventLoop._create_server_getaddrinfo() — used by create_server() — when resolving a host/port for the listener yields an empty list. It is an OSError signalling that name resolution produced no usable records for the requested family/flags (default AI_PASSIVE).

Source

Thrown at Lib/asyncio/base_events.py:1539

    async def _ensure_resolved(self, address, *,
                               family=0, type=socket.SOCK_STREAM,
                               proto=0, flags=0, loop):
        host, port = address[:2]
        info = _ipaddr_info(host, port, family, type, proto, *address[2:])
        if info is not None:
            # "host" is already a resolved IP.
            return [info]
        else:
            return await loop.getaddrinfo(host, port, family=family, type=type,
                                          proto=proto, flags=flags)

    async def _create_server_getaddrinfo(self, host, port, family, flags):
        infos = await self._ensure_resolved((host, port), family=family,
                                            type=socket.SOCK_STREAM,
                                            flags=flags, loop=self)
        if not infos:
            raise OSError(f'getaddrinfo({host!r}) returned empty list')
        return infos

    async def create_server(
            self, protocol_factory, host=None, port=None,
            *,
            family=socket.AF_UNSPEC,
            flags=socket.AI_PASSIVE,
            sock=None,
            backlog=100,
            ssl=None,
            reuse_address=None,
            reuse_port=None,
            keep_alive=None,
            ssl_handshake_timeout=None,
            ssl_shutdown_timeout=None,
            start_serving=True):
        """Create a TCP server.

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Test resolution first: socket.getaddrinfo(host, port, family, socket.AI_PASSIVE) and inspect the result
  2. Use explicit IP literals (127.0.0.1, ::1) or None for all interfaces to bypass DNS entirely
  3. Align family= with the records that actually exist for the host; fix container/host DNS if records should exist

Example fix

# before
server = await loop.create_server(factory, 'api.example.com', 8443, family=socket.AF_INET)

# after
server = await loop.create_server(factory, '127.0.0.1', 8443)  # literal, no DNS
Defensive patterns

Strategy: try-catch

Validate before calling

infos = socket.getaddrinfo(host, port, family, socket.SOCK_STREAM, flags=socket.AI_PASSIVE)
if not infos:
    host = '0.0.0.0'  # or '::' — fall back to a literal bind

Try / catch

try:
    server = await loop.create_server(factory, host, port)
except OSError as e:
    if 'returned empty list' in str(e):
        server = await loop.create_server(factory, None, port)  # all interfaces, no DNS
    else:
        raise

Prevention

When it happens

Trigger: loop.create_server(factory, 'some.host', 8080) where the host resolves to no records for the allowed family; e.g. an IPv6-only name with family=AF_INET, or AI_PASSIVE filtering everything out on a broken resolver.

Common situations: Binding a server to a hostname in a container with broken DNS; specifying a hostname that only has AAAA records while forcing AF_INET; typo'd hostname that resolves to NXDOMAIN in some resolvers behaves as empty list rather than gaierror.

Understand the failure class

Related errors


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