python/cpython · error · ValueError
Invalid address: must be None or {self._address}
Error message
Invalid address: must be None or {self._address} What it means
Raised by _SelectorDatagramTransport.sendto() as ValueError when the transport was created with a fixed remote address (remote_addr=... to create_datagram_endpoint, making it 'connected') and the caller supplies an addr that is neither None nor exactly that bound address. A connected UDP socket can only talk to its designated peer, so asyncio enforces the mismatch check.
Source
Thrown at Lib/asyncio/selector_events.py:1279
except (BlockingIOError, InterruptedError):
pass
except OSError as exc:
self._protocol.error_received(exc)
except (SystemExit, KeyboardInterrupt):
raise
except BaseException as exc:
self._fatal_error(exc, 'Fatal read error on datagram transport')
else:
self._protocol.datagram_received(data, addr)
def sendto(self, data, addr=None):
if not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError(f'data argument must be a bytes-like object, '
f'not {type(data).__name__!r}')
if self._address:
if addr not in (None, self._address):
raise ValueError(
f'Invalid address: must be None or {self._address}')
addr = self._address
if self._conn_lost and self._address:
if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
logger.warning('socket.send() raised exception.')
self._conn_lost += 1
return
if not self._buffer:
# Attempt to send it right away first.
try:
if self._extra['peername']:
self._sock.send(data)
else:
self._sock.sendto(data, addr)
return
except (BlockingIOError, InterruptedError):View on GitHub (pinned to bc6749cc3b)
Solutions
- On a transport created with remote_addr, always send with addr=None (or the identical tuple) so it goes to the bound peer.
- If you must send to arbitrary destinations, create the endpoint WITHOUT remote_addr and pass the full address each sendto().
- Normalize addresses (resolve via socket.getaddrinfo) before comparing or storing the expected peer address.
Example fix
// before
transport, _ = await loop.create_datagram_endpoint(
lambda: Proto(), remote_addr=('10.0.0.1', 9000))
transport.sendto(data, ('10.0.0.1', 9000)) # may fail if tuple form differs
// after
transport.sendto(data) # addr=None -> bound remote_addr
# or, for many peers, omit remote_addr entirely:
# transport.sendto(data, peer_addr) Defensive patterns
Strategy: validation
Validate before calling
# For a transport created with remote_addr, always send with addr=None:
transport.sendto(data) # -> bound peer
# Or normalize before comparing:
import socket
def same_addr(a, b):
ra = socket.getaddrinfo(*a[:2], type=socket.SOCK_DGRAM)[0][4]
rb = socket.getaddrinfo(*b[:2], type=socket.SOCK_DGRAM)[0][4]
return ra == rb Try / catch
try:
transport.sendto(data, addr)
except ValueError as e:
if 'Invalid address' in str(e):
transport.sendto(data) # fall back to the bound remote address
else:
raise Prevention
- Decide per endpoint: fixed peer -> use remote_addr and addr=None; many peers -> no remote_addr.
- Never forward datagram_received's addr into sendto on a connected transport.
- Store the peer tuple exactly as getaddrinfo produced it to avoid tuple mismatches.
When it happens
Trigger: loop.create_datagram_endpoint(protocol, remote_addr=('10.0.0.1', 9000)) then transport.sendto(data, ('10.0.0.2', 9001)); the address comparison is exact, so even an equal-meaning tuple that differs in form fails.
Common situations: A UDP client written to reply to the address a datagram arrived from (addr from datagram_received) instead of passing None; reusing a connected-transport code path for multiple peers; address normalization differences (e.g. '127.0.0.1' vs hostname resolution result) causing tuple mismatch.
Related errors
- data argument must be a bytes-like object, not {type(data)._
- Unimplemented ioctl request
- A datagram socket was expected, got {sock!r}
- socket modifier keyword arguments can not be used when sock
- unexpected address family
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/857f21e17b693bc0.
Report an issue: GitHub.