WARNING

How to Fix Linux ETIMEDOUT

Quick Fix Summary

TL;DR

Check firewall rules, verify network connectivity, and increase socket timeout values.

ETIMEDOUT indicates a network connection attempt failed because the remote host did not respond within the allotted time. This is a TCP/IP layer error, distinct from a refused connection.

Diagnosis & Causes

  • Network firewall blocking outbound/inbound traffic.
  • Remote service is down or unresponsive.
  • Incorrect DNS resolution leading to wrong IP.
  • System's TCP timeout values are too low.
  • Network congestion or packet loss on the route.
  • Recovery Steps

    1

    Step 1: Diagnose Network Path and Service Health

    First, rule out basic network and service issues. Use these commands to test connectivity, DNS, and check if the remote port is open.

    bash
    # 1. Test basic connectivity to the host
    ping -c 4 example.com
    # 2. Check if the specific TCP port is reachable
    nc -zv example.com 443
    # 3. Verify DNS resolution
    dig +short example.com
    host example.com
    # 4. Trace the route to identify where packets drop
    traceroute example.com
    mtr --report example.com
    2

    Step 2: Inspect and Configure Local Firewall (iptables/nftables)

    Ensure the local firewall is not blocking the outbound connection or the response. List current rules and allow traffic if needed.

    bash
    # For iptables: List all rules for the OUTPUT chain
    sudo iptables -L OUTPUT -v -n
    # For nftables: List all rules
    sudo nft list ruleset
    # Example: Allow all outbound traffic (Adjust for your security policy)
    sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
    # To make iptables rules persistent (Debian/Ubuntu)
    sudo apt-get install iptables-persistent
    sudo netfilter-persistent save
    3

    Step 3: Adjust System-Wide TCP Socket Timeouts

    Increase kernel TCP timeout parameters for connection establishment. This is critical for slow or congested networks.

    bash
    # View current timeout settings
    sysctl net.ipv4.tcp_syn_retries net.ipv4.tcp_synack_retries net.ipv4.tcp_keepalive_time
    # Temporarily increase retry attempts and intervals (Survives reboot)
    sudo sysctl -w net.ipv4.tcp_syn_retries=6
    sudo sysctl -w net.ipv4.tcp_synack_retries=5
    sudo sysctl -w net.ipv4.tcp_keepalive_time=300
    # Make changes permanent by adding to /etc/sysctl.conf
    echo 'net.ipv4.tcp_syn_retries = 6' | sudo tee -a /etc/sysctl.conf
    echo 'net.ipv4.tcp_synack_retries = 5' | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
    4

    Step 4: Implement Application-Level Timeout and Retry Logic

    For critical applications, implement graceful timeout handling and retries within your code to withstand transient network issues.

    python
    # Python example with socket timeout and retries
    import socket
    import time
    def connect_with_retry(host, port, retries=3, timeout=5):
        for attempt in range(retries):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(timeout)  # APPLICATION-LEVEL TIMEOUT
                sock.connect((host, port))
                return sock  # Connection successful
            except socket.timeout:
                print(f"Attempt {attempt+1} timed out. Retrying...")
                time.sleep(2)  # Backoff delay
            except Exception as e:
                print(f"Connection failed: {e}")
                break
        return None  # All retries failed

    Architect's Pro Tip

    "ETIMEDOUT often occurs in cloud environments during autoscaling. Pre-warm connections in your application pool and use a load balancer health check with a longer timeout to prevent false negatives."

    Frequently Asked Questions

    What's the difference between ETIMEDOUT and ECONNREFUSED?

    ETIMEDOUT means the remote host didn't respond (firewall, routing, down host). ECONNREFUSED means the host responded but nothing is listening on the target port (service not running).

    Can a DNS issue cause ETIMEDOUT?

    Indirectly. If DNS returns a stale or unreachable IP address, your connection attempts will go to the wrong host and timeout, manifesting as ETIMEDOUT.

    How do I debug ETIMEDOUT for a specific application like curl or a database client?

    Use verbose modes (e.g., `curl -v`, `mysql --verbose`), strace (`strace -e trace=network <command>`), or tcpdump (`sudo tcpdump -i any host <target_ip>`) to see the exact socket call that fails.

    Related Linux Guides