nginx/nginx · error
NGX_LOG_CRIT
NGX_LOG_CRIT
Error message
getsockname() of the inherited socket #%d failed
What it means
During a binary upgrade (SIGUSR2) the new master parses the NGX environment variable, which lists listening sockets inherited from the old master, and calls getsockname() on each fd to recover its address. If the syscall fails, this CRIT is logged and the socket is marked ignore=1: that fd's address is dropped from the new master's listener set.
Source
Thrown at src/core/ngx_connection.c:164
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
int timeout;
#endif
#if (NGX_HAVE_REUSEPORT)
int reuseport;
#endif
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(ngx_sockaddr_t));
if (ls[i].sockaddr == NULL) {
return NGX_ERROR;
}
ls[i].socklen = sizeof(ngx_sockaddr_t);
if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
"getsockname() of the inherited "
"socket #%d failed", ls[i].fd);
ls[i].ignore = 1;
continue;
}
if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
ls[i].socklen = sizeof(ngx_sockaddr_t);
}
switch (ls[i].sockaddr->sa_family) {
#if (NGX_HAVE_INET6)
case AF_INET6:
ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
break;
#endifView on GitHub (pinned to 3f6f7824d4)
Solutions
- Abort the broken new master (TERM it) and either retry the upgrade with the documented 'kill -USR2 $(cat /run/nginx.pid)' flow or do a clean restart from the service manager
- Never set or edit NGX manually - only the value nginx itself writes is valid
- Inspect the old master's environment and fds: 'tr "\0" "\n" < /proc/$(cat /run/nginx.pid)/environ | grep ^NGX=' and 'ls -l /proc/<oldpid>/fd'
- Remove supervisors that rewrite the environment around the USR2 handoff, or switch to systemd-managed restarts for upgrades
Example fix
# before (hand-set inherited sockets - corrupts fd assumptions) NGX='3:4;' /usr/sbin/nginx # after (correct binary upgrade) kill -USR2 $(cat /run/nginx.pid)
Defensive patterns
Strategy: fallback
Validate before calling
# before any USR2 upgrade, sanity-check the old master's inherited-socket environment old=$(cat /run/nginx.pid) tr '\0' '\n' < /proc/$old/environ | grep '^NGX=' ls -l /proc/$old/fd | awk '$NF ~ /socket/' | wc -l
Prevention
- Use only 'kill -USR2 <pid>' for live upgrades; never hand-write NGX
- After USR2, verify the new master inherited all listeners before QUITting the old one
- Keep a systemd-initiated restart as the fallback path when upgrade checks fail
When it happens
Trigger: Starting the new binary with a stale or hand-crafted NGX variable; the old master closed the fds between the child inheriting NGX and the getsockname call; fd numbers shifted because a wrapper altered the environment; NGX pointing at non-listening fds.
Common situations: Custom upgrade scripts that copy or rewrite the environment instead of letting nginx pass NGX itself; supervisors (supervisord, custom wrappers) scrubbing env between masters; an aborted earlier upgrade leaving stale state; accidentally exporting NGX before a fresh 'nginx' start.
Related errors
- NGX_LOG_ALERT
- NGX_LOG_ALERT
- NGX_LOG_ERR
- NGX_LOG_ERR
- limiting requests%s, excess: %ui.%03ui by zone \"%V\"
AI-assisted analysis of nginx/nginx@3f6f7824d4 (2026-08-22).
Data as JSON: /api/errors/0af48f00dcf25d71.
Report an issue: GitHub.