python/cpython · error · ValueError

A datagram socket was expected, got {sock!r}

Error message

A datagram socket was expected, got {sock!r}

What it means

Raised by create_datagram_endpoint() when a pre-created socket is passed via sock= but its type is SOCK_STREAM. UDP endpoints require a datagram (SOCK_DGRAM) socket; a TCP socket cannot carry datagram semantics.

Source

Thrown at Lib/asyncio/base_events.py:1396

        try:
            await waiter
        except BaseException:
            transport.close()
            conmade_cb.cancel()
            resume_cb.cancel()
            raise

        return ssl_protocol._app_transport

    async def create_datagram_endpoint(self, protocol_factory,
                                       local_addr=None, remote_addr=None, *,
                                       family=0, proto=0, flags=0,
                                       reuse_port=None,
                                       allow_broadcast=None, sock=None):
        """Create datagram connection."""
        if sock is not None:
            if sock.type == socket.SOCK_STREAM:
                raise ValueError(
                    f'A datagram socket was expected, got {sock!r}')
            if (local_addr or remote_addr or
                    family or proto or flags or
                    reuse_port or allow_broadcast):
                # show the problematic kwargs in exception msg
                opts = dict(local_addr=local_addr, remote_addr=remote_addr,
                            family=family, proto=proto, flags=flags,
                            reuse_port=reuse_port,
                            allow_broadcast=allow_broadcast)
                problems = ', '.join(f'{k}={v}' for k, v in opts.items() if v)
                raise ValueError(
                    f'socket modifier keyword arguments can not be used '
                    f'when sock is specified. ({problems})')
            sock.setblocking(False)
            r_addr = None
        else:
            if not (local_addr or remote_addr):
                if family == 0:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Create the socket as a datagram socket: socket.socket(family, socket.SOCK_DGRAM) before passing it
  2. If you actually need a stream connection, use loop.create_connection() (or connect_accepted_socket) instead of create_datagram_endpoint()
  3. Double-check the socket type at runtime with sock.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE) before passing it

Example fix

# before
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
await loop.create_datagram_endpoint(factory, sock=sock)

# after
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
await loop.create_datagram_endpoint(factory, sock=sock)
Defensive patterns

Strategy: validation

Validate before calling

import socket
if sock.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE) != socket.SOCK_DGRAM:
    raise ValueError(f'need SOCK_DGRAM, got {sock!r}')
transport, protocol = await loop.create_datagram_endpoint(factory, sock=sock)

Prevention

When it happens

Trigger: Calling loop.create_datagram_endpoint(protocol_factory, sock=tcp_sock) where tcp_sock was created with socket.socket(socket.AF_INET, socket.SOCK_STREAM) or obtained from a TCP accept/connect.

Common situations: Copy-pasting socket-creation code from a TCP example into a UDP endpoint; passing a socket from a connection pool or a library that only creates stream sockets; confusing SOCK_STREAM vs SOCK_DGRAM constants.

Related errors


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