ConnectionError

The OSError branch for sockets and pipes. Four subclasses tell you what happened: nobody listening (refused), the peer hung up (reset / broken pipe), or the connection was dropped locally (aborted).

InheritsBaseException›Exception›OSError›ConnectionError
OS exceptionPython 3.3+Live demo
ConnectionError(*args)
Raised by
socket connect/send/recv, http.client, urllib, asyncio streams, writing to a closed pipe
Message
[Errno N] Connection refused / Connection reset by peer / Broken pipe
Quick fix
except ConnectionError: retry with backoff
Watch out
TimeoutError is NOT a ConnectionError

Demo

Live evaluation
The socket layer raises OSError with an errno; the constructor turns each connection errno into its subclass. Pick one: pipe, aborted, refused, reset.
Try:
Inputs
kindstrpipe / aborted / refused / reset
Code
import errno
codes = {'pipe': errno.EPIPE, 'aborted': errno.ECONNABORTED,
         'refused': errno.ECONNREFUSED, 'reset': errno.ECONNRESET}
e = OSError(codes['refused'], 'simulated')
(type(e).__name__, isinstance(e, ConnectionError))
Result
('ConnectionRefusedError', True)

Trigger never names a subclass, yet every result is a specific one — errno picked it. The codes use the errno.NAME constants because the numbers differ by OS (ECONNREFUSED is 111 on Linux, 61 on macOS, 10061 on Windows). In Handle, timeout escapes the except ConnectionError clause: TimeoutError is a sibling, not a child.

Constructor

NameTypeRequiredDescription
*argsobjectnoA message, or (errno, strerror) like any OSError. Subclasses are usually raised by the socket layer, not constructed by hand.

Attributes

AttributeTypeMeaning
errnoint | Noneerrno.EPIPE / ESHUTDOWN, ECONNABORTED, ECONNREFUSED or ECONNRESET when raised by the OS. Compare with the errno constants, not numbers.
strerrorstr | NoneOS text, e.g. 'Connection refused' on Linux; Windows uses its own wording ('No connection could be made because the target machine actively refused it').
winerrorintWindows only: 10061 (refused), 10054 (reset), 10053 (aborted) …

Common patterns

Retry transient network failures
Refused and reset connections are often temporary (server restarting). Retry with backoff; include TimeoutError.
import time
for attempt in range(5):
    try:
        conn = connect()
        break
    except (ConnectionError, TimeoutError):
        if attempt == 4:
            raise
        time.sleep(2 ** attempt)
Quiet exit when stdout is closed
python script.py | head closes the pipe early; the next print raises BrokenPipeError. Exit quietly instead of printing a traceback.
import os, sys
try:
    for line in lines:
        print(line)
    sys.stdout.flush()
except BrokenPipeError:
    devnull = os.open(os.devnull, os.O_WRONLY)
    os.dup2(devnull, sys.stdout.fileno())
    sys.exit(1)
Server: ignore clients that vanish
A client closing mid-response is normal for a server; log it and move on.
try:
    conn.sendall(payload)
except (BrokenPipeError, ConnectionResetError):
    log.info('client went away')

Examples

1. EPIPE becomes BrokenPipeError
import errno raise OSError(errno.EPIPE, 'Broken pipe')
Returns
BrokenPipeError: [Errno 32] Broken pipe
2. Each errno has its subclass
import errno [type(OSError(c, 'x')).__name__ for c in (errno.ECONNABORTED, errno.ECONNREFUSED, errno.ECONNRESET)]
Returns
['ConnectionAbortedError', 'ConnectionRefusedError', 'ConnectionResetError']
3. ESHUTDOWN is a broken pipe too
import errno type(OSError(errno.ESHUTDOWN, 'Cannot send after transport endpoint shutdown')).__name__
Returns
'BrokenPipeError'
4. All four are ConnectionErrors
[issubclass(c, ConnectionError) for c in (BrokenPipeError, ConnectionAbortedError, ConnectionRefusedError, ConnectionResetError)]
Returns
[True, True, True, True]
5. TimeoutError is not one
(issubclass(TimeoutError, ConnectionError), issubclass(TimeoutError, OSError))
Returns
(False, True)
6. Check the errno by name
import errno e = OSError(errno.ECONNRESET, 'Connection reset by peer') (type(e).__name__, e.errno == errno.ECONNRESET)
Returns
('ConnectionResetError', True)
7. Raise one yourself
raise ConnectionRefusedError('db:5432 is not accepting connections')
Returns
ConnectionRefusedError: db:5432 is not accepting connections

Pitfalls

1. Retrying only on refused
A server that restarts can refuse new connections AND reset existing ones. Catching one subclass lets the other crash the client.
except ConnectionRefusedError
try:
    raise ConnectionResetError('peer closed the connection')
except ConnectionRefusedError:
    r = 'retry'
r
ConnectionResetError: peer closed the connection
except ConnectionError
try:
    raise ConnectionResetError('peer closed the connection')
except ConnectionError:
    r = 'retry'
r
'retry'
2. Assuming ConnectionError covers timeouts
A slow server raises TimeoutError, which sits next to ConnectionError under OSError. Network retry code needs both.
ConnectionError only
def call():
    raise TimeoutError('timed out')
try:
    call()
except ConnectionError:
    r = 'retry'
r
TimeoutError: timed out
(ConnectionError, TimeoutError)
def call():
    raise TimeoutError('timed out')
try:
    call()
except (ConnectionError, TimeoutError):
    r = 'retry'
r
'retry'

When to use

Use it
  • Retry logic around sockets, HTTP clients built on the stdlib, database drivers that surface OSErrors
  • Handling clients that disconnect mid-request on a server
  • Raising it from your own client code when the remote end misbehaves
Reach for something else
  • Timeouts → also catch TimeoutError
  • requests / httpx → catch their own ConnectionError classes (not the built-in one)
  • DNS failures → socket.gaierror (an OSError, not a ConnectionError)

Notes

CPython impl
Objects/exceptions.c — EPIPE and ESHUTDOWN → BrokenPipeError, ECONNABORTED → ConnectionAbortedError, ECONNREFUSED → ConnectionRefusedError, ECONNRESET → ConnectionResetError
Catch via
except ConnectionError for all four; except OSError also catches TimeoutError and the rest
errno numbers
Connection errnos differ per OS (ECONNRESET: 104 Linux, 54 macOS, 10054 Windows) — always compare with errno.ECONNRESET

FAQ

The target host answered, but nothing is listening on that port: the server is not running, listens on another port or interface (127.0.0.1 vs 0.0.0.0), or a firewall rejects the connection. Windows shows it as [WinError 10061] No connection could be made because the target machine actively refused it; macOS as [Errno 61].

History

3.3
Added with BrokenPipeError, ConnectionAbortedError, ConnectionRefusedError and ConnectionResetError (PEP 3151).