CRITICAL

How to Fix Linux EADDRINUSE: Address Already in Use

Quick Fix Summary

TL;DR

Identify and kill the process holding the port, then restart your service.

The EADDRINUSE error occurs when a process attempts to bind a socket (TCP/UDP) to a network port and IP address combination that is already in use by another process. This prevents your application from starting and will cause immediate service downtime.

Diagnosis & Causes

  • Previous service instance failed to terminate cleanly.
  • Another application is configured to use the same port.
  • Container or process restart left sockets in TIME_WAIT state.
  • SO_REUSEADDR socket option not set for rapid restarts.
  • Orphaned child processes holding open file descriptors.
  • Recovery Steps

    1

    Step 1: Identify the Occupying Process

    Use `ss` or `lsof` to find the PID and command of the process holding your port.

    bash
    # Find process using port 8080 (TCP)
    ss -ltnp 'sport = :8080'
    # Alternative using lsof (install if needed)
    sudo lsof -i :8080
    2

    Step 2: Terminate the Conflicting Process

    Gracefully stop the identified process. Use SIGTERM first, then SIGKILL if necessary.

    bash
    # Graceful termination
    sudo kill -15 <PID>
    # Force kill if unresponsive (use cautiously)
    sudo kill -9 <PID>
    3

    Step 3: Verify Port is Released

    Confirm the port is free before restarting your application.

    bash
    # Check if port 8080 is now free
    ss -ltn 'sport = :8080'
    # Should return no output if free
    4

    Step 4: Implement SO_REUSEADDR in Your Application

    Modify your application code to set the SO_REUSEADDR socket option, allowing immediate reuse of the port after the previous process ends.

    python
    // Python Example
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('0.0.0.0', 8080))
    5

    Step 5: Handle TIME_WAIT States (Kernel Parameters)

    For high-frequency restarts, tune kernel TCP parameters to reduce the TIME_WAIT duration, allowing faster port reuse.

    bash
    # Make TIME_WAIT sockets reusable faster
    sudo sysctl -w net.ipv4.tcp_tw_reuse=1
    # Reduce TIME_WAIT timeout (default 60s)
    sudo sysctl -w net.ipv4.tcp_fin_timeout=30
    # Apply changes persistently
    echo 'net.ipv4.tcp_tw_reuse=1' | sudo tee -a /etc/sysctl.conf
    6

    Step 6: Use a Wrapper Script for Clean Restarts

    Create a deployment/restart script that always checks for and cleans up the target port before launching.

    bash
    #!/bin/bash
    PORT=8080
    PID=$(ss -ltnp "sport = :$PORT" | grep -oP 'pid=\K\d+')
    [[ -n "$PID" ]] && \
      kill -15 $PID 2>/dev/null && \
      sleep 2
    # Now start your application
    /usr/bin/your-application --port $PORT

    Architect's Pro Tip

    "For containerized environments (Docker/K8s), use `lsof -i` inside the container namespace: `nsenter -t <PID> -n lsof -i :<PORT>` to diagnose without entering the container."

    Frequently Asked Questions

    What's the difference between `ss`, `netstat`, and `lsof` for diagnosing EADDRINUSE?

    `ss` (socket statistics) is modern, faster, and supplied with the kernel. `netstat` is legacy but widely known. `lsof` (list open files) provides the most detailed process information but may need installation. Use `ss` for speed in scripts.

    Why does EADDRINUSE still occur immediately after killing a process?

    This is typically due to TCP sockets in the TIME_WAIT state (lasting 60s by default). The kernel maintains this state to handle late-arriving packets. Use `SO_REUSEADDR` in your code or tune `net.ipv4.tcp_tw_reuse` to mitigate this.

    Is it safe to use `kill -9` (SIGKILL) to resolve EADDRINUSE?

    Only as a last resort. SIGKILL prevents the process from cleaning up resources (files, child processes, IPC). Always try `kill -15` (SIGTERM) first, wait a few seconds, then use SIGKILL if the process is unresponsive.

    Related Linux Guides