python/cpython · error · ExceptionGroup

create_connection failed

Error message

create_connection failed

What it means

The message of the ExceptionGroup raised by create_connection (Python 3.11+ with all_errors=True, or 3.12+ where all_errors defaults True) when every connection attempt failed. Each attempted address contributed one exception; asyncio groups them so the caller can inspect all root causes (DNS, refused, timeouts) rather than just the first. The group itself is an ExceptionGroup, not an OSError.

Source

Thrown at Lib/asyncio/base_events.py:1172

            else:  # using happy eyeballs
                sock = (await staggered.staggered_race(
                    (
                        # can't use functools.partial as it keeps a reference
                        # to exceptions
                        lambda addrinfo=addrinfo: self._connect_sock(
                            exceptions, addrinfo, laddr_infos
                        )
                        for addrinfo in infos
                    ),
                    happy_eyeballs_delay,
                    loop=self,
                ))[0]  # can't use sock, _, _ as it keeks a reference to exceptions

            if sock is None:
                exceptions = [exc for sub in exceptions for exc in sub]
                try:
                    if all_errors:
                        raise ExceptionGroup("create_connection failed", exceptions)
                    if len(exceptions) == 1:
                        raise exceptions[0]
                    elif exceptions:
                        # If they all have the same str(), raise one.
                        model = str(exceptions[0])
                        if all(str(exc) == model for exc in exceptions):
                            raise exceptions[0]
                        # Raise a combined exception so the user can see all
                        # the various error messages.
                        raise OSError('Multiple exceptions: {}'.format(
                            ', '.join(str(exc) for exc in exceptions)))
                    else:
                        # No exceptions were collected, raise a timeout error
                        raise TimeoutError('create_connection failed')
                finally:
                    exceptions = None

        else:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Catch ExceptionGroup (or use except* syntax) and inspect .exceptions for root causes.
  2. Pass all_errors=False to get legacy behavior (single exception or combined OSError), if compatibility matters.
  3. Retry at a higher level with backoff once you have logged the per-address causes.

Example fix

// before
try:
    await loop.create_connection(proto, host, port)
except OSError as e:  # misses ExceptionGroup on 3.12+
    log(e)

// after
try:
    await loop.create_connection(proto, host, port)
except* OSError as eg:
    for exc in eg.exceptions:
        log(f'attempt failed: {exc!r}')
Defensive patterns

Strategy: try-catch

Try / catch

try:
    tp, pr = await loop.create_connection(proto, host, port)
except* OSError as eg:
    for exc in eg.exceptions:
        log.warning(f'connect attempt failed: {exc!r}')
    raise
except ExceptionGroup as eg:
    for exc in eg.exceptions:
        log.warning(f'connect attempt failed: {exc!r}')
    raise

Prevention

When it happens

Trigger: loop.create_connection(..., all_errors=True) to a multi-address host (dual-stack A+AAAA) where both the IPv6 and IPv4 attempts fail — e.g. firewall drops v6 (timeout) and v4 gets ECONNREFUSED. Catching OSError alone will NOT catch this ExceptionGroup.

Common situations: Upgrading to Python 3.12 where all_errors defaulted to True changed exception types; servers reachable on only one family; flaky networks where different attempts fail differently.

Related errors


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