ERROR

How to Fix Nginx Upstream: Firewall Connection Refused

Quick Fix Summary

TL;DR

Check and open the firewall port on the upstream server, then verify Nginx can connect.

Nginx cannot establish a TCP connection to the backend server defined in the upstream block. The connection is actively refused, typically by a firewall or because the service isn't listening.

Diagnosis & Causes

  • Firewall on upstream server blocking the port.
  • Upstream service not running or crashed.
  • Nginx upstream directive points to wrong IP/port.
  • Upstream server's local firewall (e.g., iptables, firewalld) is active.
  • Network Security Groups (Cloud) blocking internal traffic.
  • Recovery Steps

    1

    Step 1: Verify Upstream Service Status

    First, SSH into the upstream server and confirm the target service is running and listening on the expected port.

    bash
    # Check if the service is running
    sudo systemctl status <service_name>
    # Check what's listening on the target port (e.g., 8080)
    sudo ss -tlnp | grep :8080
    sudo netstat -tlnp | grep :8080
    2

    Step 2: Test Basic Connectivity from Nginx Server

    From the Nginx server, use telnet or nc to test if the TCP port is open. A 'Connection refused' here confirms the firewall/network issue.

    bash
    # Test connection to upstream server on port 8080
    telnet <upstream_server_ip> 8080
    # Or using netcat (nc)
    nc -zv <upstream_server_ip> 8080
    3

    Step 3: Check Local Firewall on Upstream Server (iptables/firewalld)

    If the service is running but unreachable, inspect and configure the local firewall on the upstream host.

    bash
    # For firewalld (RHEL/CentOS/Fedora)
    sudo firewall-cmd --list-all
    sudo firewall-cmd --permanent --add-port=8080/tcp
    sudo firewall-cmd --reload
    # For iptables (Ubuntu/Debian)
    sudo iptables -L -n -v | grep 8080
    sudo ufw status verbose
    4

    Step 4: Check Cloud Provider Network Security Groups

    In AWS, GCP, or Azure, ensure the Security Group or Firewall rule allows traffic from the Nginx server's IP/security group to the upstream port.

    bash
    # This is platform-specific. General check:
    # 1. Identify the upstream server's Security Group.
    # 2. Verify an INBOUND rule exists for the Nginx server's IP/security group on the upstream port (e.g., TCP 8080).
    # 3. For private VPCs, ensure both instances are in the same subnet or routing is correct.
    5

    Step 5: Verify Nginx Upstream Configuration

    Ensure the Nginx config points to the correct upstream server IP and port, and consider adding timeouts and retry logic.

    nginx
    http {
        upstream backend {
            server 10.0.1.5:8080 max_fails=3 fail_timeout=30s; # Correct IP:Port
            # server unix:/tmp/backend.sock; # Alternative socket
        }
        server {
            location / {
                proxy_pass http://backend;
                proxy_connect_timeout 5s; # Fail fast on connection issues
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
            }
        }
    }
    6

    Step 6: Test and Reload Nginx

    After making changes, test the configuration syntax and gracefully reload Nginx to apply fixes without dropping connections.

    bash
    # Test configuration for syntax errors
    sudo nginx -t
    # If test passes, reload Nginx
    sudo systemctl reload nginx
    # Or use the direct signal
    sudo nginx -s reload

    Architect's Pro Tip

    "Use `tcpdump` on the upstream server (`sudo tcpdump -i any port 8080 -n`) to see if SYN packets from Nginx are arriving. No packets? It's a network/firewall block. SYN seen but RST returned? The service isn't listening."

    Frequently Asked Questions

    My Nginx and upstream are on the same host. Can I still get this error?

    Yes. If using `localhost` or `127.0.0.1`, ensure the service is listening on all interfaces (`0.0.0.0:port`) and not just a specific IP. Also, check local firewall rules (like `iptables`).

    What's the difference between 'connection refused' and 'connection timed out'?

    'Connection refused' means the TCP SYN packet reached the host, but nothing is listening on the port (firewall rejected it). 'Connection timed out' means the SYN packet never reached the host (network route/security group issue).

    Should I open the upstream port to the public internet to fix this?

    Never. Only allow traffic from your Nginx server's specific IP address or private security group. Opening to `0.0.0.0/0` is a critical security vulnerability.

    Related Nginx Guides