Nginx Error: 'socket() [::]:80 failed (97: Address family not supported by protocol)' — Cause, Fix, and Troubleshooting Guide
Fix nginx 'socket() [::]:80 failed (97: Address family not supported by protocol)': IPv6 disabled or missing when using listen [::]:80.
- #nginx
- #web-server
- #troubleshooting
- #config
Stuck on this NGINX error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
What this error means
Nginx logs this at startup when a listen directive asks it to bind an IPv6 socket (listen [::]:80;) but the kernel cannot create an IPv6 socket — because IPv6 has been disabled or the IPv6 stack is not available:
2026/07/12 09:14:02 [emerg] 1188#1188: socket() [::]:80 failed (97: Address family not supported by protocol)
Error 97 is the POSIX errno EAFNOSUPPORT (“address family not supported by protocol”), returned by the socket(AF_INET6, ...) syscall when the AF_INET6 family is unavailable. Because this is an [emerg] during startup, nginx fails to start (or a reload aborts and the old workers keep running with the previous config). The site is down until the config no longer requires an IPv6 socket the kernel will not provide.
How it presents
nginx -tpasses (syntax is valid) butsystemctl start nginxfails.journalctl -u nginxshowssocket() [::]:80 failed (97: Address family not supported by protocol).- The failure appeared after adding
listen [::]:80;orlisten [::]:443 ssl;to a server block. - The failure appeared after a kernel/boot change that set
ipv6.disable=1or blacklisted theipv6module. - A reload succeeds visually but
nginx -s reloadlogs the emerg and the new config never takes effect. ip -6 addrshows no IPv6 addresses, andls /proc/sys/net/ipv6is missing.
Tracing the connection
First confirm nginx really fails to start and capture the emerg line:
sudo nginx -t
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx --since "10 min ago" --no-pager
Find which server block introduced the IPv6 listener:
sudo nginx -T | grep -n "listen .*\[::\]"
Check whether the kernel actually supports IPv6 right now:
# Is IPv6 disabled at the kernel level?
cat /proc/sys/net/ipv6/conf/all/disable_ipv6 2>/dev/null || echo "no /proc/sys/net/ipv6 — IPv6 not present"
# Was it disabled on the boot command line?
grep -o 'ipv6.disable=[01]' /proc/cmdline || echo "ipv6.disable not on cmdline"
# Any IPv6 addresses on interfaces?
ip -6 addr show
If /proc/sys/net/ipv6 does not exist, or disable_ipv6 reads 1, or ipv6.disable=1 is on the command line, the kernel will refuse every AF_INET6 socket and nginx cannot bind [::].
Network path causes
- IPv6 disabled at boot — the kernel was booted with
ipv6.disable=1on the command line, so noAF_INET6sockets can be created at all, and anylisten [::]fails. ipv6module blacklisted — a modprobe blacklist ornet.ipv6.conf.all.disable_ipv6=1sysctl removed IPv6 support that nginx’s config still assumes.- Config copied from an IPv6-capable host — a server block with
listen [::]:80;was reused on a host (often a minimal container or VM image) that never had IPv6 enabled. - Container/runtime without IPv6 — the container runtime did not enable IPv6 networking, so the namespace has no IPv6 stack even though the image’s nginx config lists
[::]listeners. ipv6onlyassumptions — a singlelisten [::]:80;was intended to serve both families, but with IPv6 unavailable there is no working socket at all.
Remediation steps
You have two directions: make IPv6 available, or stop nginx from requiring it. Choose based on whether the host is supposed to serve IPv6.
Option A — enable IPv6 (preferred if the host should serve IPv6). If it was disabled by sysctl, re-enable it:
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=0
# persist:
echo -e "net.ipv6.conf.all.disable_ipv6=0\nnet.ipv6.conf.default.disable_ipv6=0" \
| sudo tee /etc/sysctl.d/99-enable-ipv6.conf
sudo sysctl --system
If it was disabled on the boot line, remove ipv6.disable=1 from the kernel command line (e.g. in /etc/default/grub), update grub, and reboot. A reboot is required for a boot-parameter change to take effect.
Option B — remove or guard the IPv6 listener on a host that has no IPv6. Drop the [::] line and keep the IPv4 listener:
server {
# Serve IPv4 only on a host without IPv6
listen 80;
# listen [::]:80; # removed: host has no IPv6 stack
server_name example.com;
# ...
}
If you keep both families, make each listener explicit with ipv6only=on so the IPv4 socket is independent and an absent IPv6 stack fails in isolation rather than taking down a dual-stack socket:
server {
listen 80;
listen [::]:80 ipv6only=on; # only add on hosts where IPv6 is present
server_name example.com;
# ...
}
Because this is a listen/socket change, validate and then restart (a reload cannot rebind listening sockets that failed to open):
sudo nginx -t && sudo systemctl restart nginx
Keeping the path healthy
nginx -tonly checks syntax; it does not attempt to bind sockets, so it passes even when[::]will fail at start. Always confirm the service actually started.- Keep host config and nginx config in sync: if an image or template ships
listen [::], only deploy it to hosts and containers that have IPv6 enabled. - Prefer explicit
ipv6only=onon dual-stack hosts so IPv4 and IPv6 listeners are independent and one family’s failure does not cascade. - Boot-parameter changes (
ipv6.disable) need a reboot; sysctl changes take effect immediately but must be persisted to survive one. - In containers, IPv6 must be enabled in the runtime/network config, not just inside the image — the namespace may lack the stack regardless of the image.
- After enabling IPv6, verify reachability end to end (
ip -6 addr, DNS AAAA records) so you do not advertise an address path that does not actually work.
Related connectivity errors
- Nginx Error: Bind Address Already In Use — the other common
listen-time bind failure, caused by a port conflict rather than a missing address family. - Nginx Error: Cannot Assign Requested Address — a related socket/address failure, from ephemeral port exhaustion or binding an address the host does not own.
- Nginx Error: Could Not Build Server Names Hash — another startup-time
[emerg]that stops nginx from booting until the config is corrected.
See the NGINX category for more guides.
Fixed it? Get 500 NGINX & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.