nginx/nginx · error

NGX_LOG_ALERT

NGX_LOG_ALERT

Error message

recvmsg() failed

What it means

recvmsg(2) on a UDP listening socket returned -1 with an errno other than EAGAIN. nginx logs it at ALERT with the errno text appended and drops this event; the listener stays healthy and processes subsequent datagrams. The errno is the key diagnostic — it names the actual kernel-level failure.

Source

Thrown at src/event/ngx_event_udp.c:98

            msg.msg_control = &msg_control;
            msg.msg_controllen = sizeof(msg_control);

            ngx_memzero(&msg_control, sizeof(msg_control));
        }
#endif

        n = recvmsg(lc->fd, &msg, 0);

        if (n == -1) {
            err = ngx_socket_errno;

            if (err == NGX_EAGAIN) {
                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
                               "recvmsg() not ready");
                return;
            }

            ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed");

            return;
        }

#if (NGX_HAVE_ADDRINFO_CMSG)
        if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
            ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
                          "recvmsg() truncated data");
            continue;
        }
#endif

        sockaddr = msg.msg_name;
        socklen = msg.msg_namelen;

        if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
            socklen = sizeof(ngx_sockaddr_t);
        }

View on GitHub (pinned to 3f6f7824d4)

Solutions

  1. Read the errno on the log line first — remediation depends entirely on it
  2. ENOBUFS / buffer pressure: raise net.core.rmem_max and net.core.rmem_default, and the per-listener rcvbuf, or shed traffic at the edge
  3. ECONNREFUSED: find what is sending to unreachable peers from this socket (health probes to dead upstreams are the usual source)
  4. If it recurs with the same errno, inspect with ss -uamp and strace -e trace=recvmsg on the worker

Example fix

# before
sysctl net.core.rmem_max=212992   # default, drops under QUIC floods

# after
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.rmem_default=1048576
# and per-listener rcvbuf if tuned
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight the datagram environment
sysctl net.core.rmem_max net.core.rmem_default
ss -uamp | grep -E 'port ${PORT}' | head

Prevention

When it happens

Trigger: Kernel errors during datagram receive: ENOBUFS under receive-buffer pressure on high-PPS UDP services (DNS, QUIC), ECONNREFUSED from an earlier ICMP error queued on the socket, or a socket in an abnormal state after binary upgrade inheritance.

Common situations: DNS or QUIC frontends under datagram floods; misbehaved NAT/containers feeding ICMP errors; sockets shared across master/worker during live upgrades.

Related errors


AI-assisted analysis of nginx/nginx@3f6f7824d4 (2026-08-22). Data as JSON: /api/errors/cb6cce6cdc26e60f. Report an issue: GitHub.