Nginx is failing to resolve external hostnames because its built-in DNS resolver configuration is missing or invalid.

The most common culprit is a missing resolver directive in your Nginx configuration, particularly in server or location blocks that make upstream requests using variables. Nginx needs to know which DNS servers to query.

Cause 1: Missing resolver Directive

  • Diagnosis: Check your nginx.conf and any included configuration files for the resolver directive within the relevant server or location blocks. If it’s not there, or commented out, this is likely the issue.
    grep -r "resolver" /etc/nginx/
    
  • Fix: Add a resolver directive pointing to valid DNS servers. For example, to use Google’s public DNS servers:
    resolver 8.8.8.8 8.8.4.4 valid=30s;
    
  • Why it works: This explicitly tells Nginx which DNS servers to use for resolving hostnames specified in directives like proxy_pass when those hostnames are variables. The valid=30s part caches DNS records for 30 seconds.

Cause 2: Invalid DNS Server IP Address

  • Diagnosis: If you have a resolver directive, ensure the IP addresses specified are reachable from your Nginx server. You can test this with ping or dig.
    ping 8.8.8.8
    dig @8.8.8.8 google.com
    
  • Fix: Replace invalid IP addresses with known good ones, such as your internal DNS servers or public ones like 1.1.1.1 (Cloudflare) or 8.8.8.8 (Google).
    resolver 1.1.1.1 1.0.0.1 valid=30s;
    
  • Why it works: Nginx can only use DNS servers that are accessible and responsive. Using correct IPs ensures the DNS resolution process can actually complete.

Cause 3: Firewall Blocking DNS Traffic

  • Diagnosis: Even if the resolver directive is correct, a firewall on the Nginx server or an intermediate network device might be blocking UDP port 53, which is used for DNS queries.
    sudo ufw status verbose # If using UFW
    sudo iptables -L -n -v # If using iptables directly
    
    Check your cloud provider’s security group rules as well.
  • Fix: Allow outbound UDP traffic on port 53 to your specified DNS servers. For iptables:
    sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
    sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT # Sometimes TCP is used as a fallback
    
    If using UFW:
    sudo ufw allow out 53/udp
    sudo ufw allow out 53/tcp
    
  • Why it works: DNS resolution relies on network communication. Opening the necessary ports ensures Nginx can send its DNS queries and receive responses.

Cause 4: resolver Directive in the Wrong Context

  • Diagnosis: The resolver directive must be placed in a context where it can be used by other directives that require name resolution. This is typically within an http block, server block, or location block that performs upstream requests (e.g., proxy_pass, uwsgi_pass, fastcgi_pass). If it’s only in a main context or a context that doesn’t perform lookups, it won’t be effective.
    # Incorrect placement (won't affect proxy_pass in a location block)
    http {
        resolver 8.8.8.8;
        server { ... }
    }
    
    # Correct placement
    http {
        server {
            resolver 8.8.8.8;
            location / {
                proxy_pass http://my_backend;
            }
        }
    }
    
  • Fix: Move the resolver directive into the http, server, or location block that contains the directive requiring name resolution (like proxy_pass).
  • Why it works: Nginx processes directives within their scope. Placing resolver in the same scope as or a parent scope of the name-resolving directive ensures Nginx can find and use the DNS server configuration when needed.

Cause 5: DNS Server Not Responding or Overloaded

  • Diagnosis: If your specified DNS servers are intermittently unavailable or overloaded, Nginx might fail to resolve names. This can be harder to diagnose directly from Nginx logs. Check the health of your DNS infrastructure.
  • Fix: Switch to more reliable DNS servers, or investigate and fix issues with your current DNS servers.
    resolver 9.9.9.9 valid=30s; # Example: Switching to Quad9
    
  • Why it works: A stable DNS resolution service is critical for Nginx to translate hostnames into IP addresses for upstream connections.

Cause 6: Using Hostnames in proxy_pass that are Not Resolvable at Nginx Startup (and resolver is missing)

  • Diagnosis: If you use a hostname in proxy_pass that Nginx tries to resolve immediately upon loading the configuration (e.g., if the hostname is static and not a variable), and resolver is not defined, it will fail.
    # This will fail if resolver is not defined, as Nginx tries to resolve 'my-app-service' on config load
    location / {
        proxy_pass http://my-app-service:8080;
    }
    
  • Fix: Ensure the resolver directive is present in the same server or location block.
    location / {
        resolver 8.8.8.8;
        proxy_pass http://my-app-service:8080;
    }
    
  • Why it works: Nginx needs the resolver directive to perform the lookup for my-app-service to translate it into an IP address that it can then connect to.

After fixing the resolver directive and ensuring DNS is functional, the next error you’ll likely encounter is related to the actual upstream service not responding, or a TLS handshake failure if you’re using HTTPS for upstream connections.

Want structured learning?

Take the full Nginx course →