python/cpython · error · OSError
Multiple exceptions: {}
Error message
Multiple exceptions: {} What it means
An OSError raised by create_connection (all_errors=False path) when multiple addresses were tried and all failed with different error strings. asyncio first tries to re-raise a single exception if there was only one attempt or all messages are identical; when they differ, it joins them into one OSError whose message is 'Multiple exceptions: ...' so the user can see every failure reason.
Source
Thrown at Lib/asyncio/base_events.py:1182
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:
if sock is None:
raise ValueError(
'host and port was not specified and no sock specified')
if sock.type != socket.SOCK_STREAM:
# We allow AF_INET, AF_INET6, AF_UNIX as long as they
# are SOCK_STREAM.
# We support passing AF_UNIX sockets even though we have
# a dedicated API for that: create_unix_connection.
# Disallowing AF_UNIX in this method, breaks backwards
# compatibility.View on GitHub (pinned to bc6749cc3b)
Solutions
- Parse or log the full message to see each underlying failure and fix the dominant one (often the first).
- Pass all_errors=True to get a structured ExceptionGroup instead of a string-joined message.
- Retry with backoff for transient network conditions once causes are known.
Example fix
// before
try:
await loop.create_connection(proto, host, port)
except OSError as e:
print(e) # opaque 'Multiple exceptions: ...'
// after
try:
await loop.create_connection(proto, host, port, all_errors=True)
except* OSError as eg:
for exc in eg.exceptions:
print(repr(exc)) # individual causes Defensive patterns
Strategy: try-catch
Try / catch
try:
tp, pr = await loop.create_connection(proto, host, port, all_errors=False)
except OSError as e:
if str(e).startswith('Multiple exceptions:'):
for part in str(e).split(', '):
log.warning(f'connect failure: {part}')
raise Prevention
- Prefer all_errors=True for structured multi-failure handling.
- Log the full message text — the joined causes identify which address family failed.
- Wrap connection setup in retry-with-backoff at the service layer.
When it happens
Trigger: Connecting to a dual-stack host where the IPv6 attempt times out and the IPv4 attempt gets 'connection refused' — two distinct messages, so the combined OSError is raised. Only reachable with all_errors=False (pre-3.12 default).
Common situations: Partial reachability (v6 blocked, v4 refused), mixed DNS/timeout failures across multiple A records, flaky uplinks during address iteration.
Related errors
- no matching local address with {family=} found
- getaddrinfo() returned empty list
- create_connection failed
- server_hostname is only meaningful with ssl
- host/port and sock can not be specified at the same time
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/d01d42ba8d80bb11.
Report an issue: GitHub.