Guides 11792 Published by

The article walks readers through turning on IPv6 support for Nginx, starting with checking whether the kernel allows binding to IPv6 addresses and enabling it if necessary. It then shows how to add explicit `listen [::]:80` (and optional SSL) directives inside a server block so that the web server can accept both IPv4 and IPv6 traffic. After performing a syntax test with `nginx -t`, the guide advises reloading the service safely, verifying connectivity with curl on the loopback address, and troubleshooting potential firewall or security module blocks. Finally, it lists common pitfalls such as duplicate listen lines, port conflicts from containers, and post‑upgrade IPv6 disables, ending by stressing that enabling IPv6 is a simple configuration tweak that ensures mobile and IPv6‑preferring visitors reach the site.



How to Enable IPv6 in Nginx and Make Your Site Reachable on All Networks

If you’ve been running a site that only responds to http://example.com for IPv4 but your visitors keep hitting the IPv6 address and getting nothing, it’s time to patch that gap. Below is a quick walk‑through of turning on IPv6 in Nginx, with a few real‑world hiccups you’ll want to watch out for.

Check Your Server Supports IPv6

Before tinkering with config files, make sure the OS can even bind to IPv6. On most modern Linux boxes this is enabled by default, but if you’re on an older Debian or a minimal container it might be off.

sysctl net.ipv6.conf.all.disable_ipv6

If that returns 1, run:

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0

Why does this matter? Nginx won’t even try to listen on IPv6 if the kernel refuses; you’ll end up with a silent 502 and no clue why.

Add an IPv6 Listen Directive

Open your site’s server block (/etc/nginx/sites-available/example) and add a listen [::]:80 line. The square brackets tell Nginx this is the IPv6 wildcard address; without them it thinks you’re using a literal string.

server {
    listen 80;
    listen [::]:80;

    server_name example.com;

    # … rest of config …
}

If you also use TLS, add:

listen 443 ssl;
listen [::]:443 ssl;

listen without an address defaults to IPv4. Adding the IPv6 version explicitly tells Nginx to bind two sockets—one for each protocol.

Validate and Reload

Running a syntax check before reloading is a lifesaver; you’ll never have to restart the service on a live site just to discover you misspelled listen.

sudo nginx -t

If it says “syntax OK” and “test failed”, fix whatever is wrong. Once cleared:

sudo systemctl reload nginx

Reloading keeps current connections alive while pulling in the new config, so your users don’t see a hiccup.

Verify IPv6 Is Working

From the server itself, curl the IPv6 loopback to confirm binding:

curl -6 http://[::1]

You should see your page’s HTML. From an external machine, ping an IPv6 address of the host (or use dig AAAA example.com) and then fetch it.

If you get “connection refused” or no reply, double‑check:

  • Firewall – On Ubuntu firewalls often block port 80/443 for IPv6 by default. Run sudo ufw allow in on eth0 to any port 80 proto tcp (adjust interface as needed).
  • SELinux/AppArmor – These security modules sometimes deny bind on IPv6. Look at /var/log/audit/audit.log or run sudo setenforce 0 temporarily to test.
That’s usually for the kernel, but the same principle applies: a recent OS upgrade can disable IPv6 without telling you. Always re‑check sysctl net.ipv6.conf.all.disable_ipv6 after an OS change.
  • Multiple Listen Lines – If you have several listen 80; directives, add [::]:80 to each or just use the one block and remove duplicates. Duplicate listens can cause Nginx to pick the first IPv4 bind and ignore IPv6.
  • Port Conflicts – A process like Docker sometimes grabs IPv6 sockets. Use netstat -tuln | grep :80 to confirm nothing else is hogging your port.
Why Bother?

If your visitors come from a mobile network that prefers IPv6, or you’re in a region where IPv4 addresses are scarce, having no IPv6 support can silently drop traffic. Enabling it is just one line of config and keeps everyone happy—no extra cost, no extra maintenance.

That’s all there is to it. If you hit a wall, drop a comment here; I’ve run into a handful of those odd quirks that aren’t in the docs.