The EADDRINUSE error means a network process tried to bind to a network address (IP address and port number) that is already occupied by another process.

Common Causes and Fixes for EADDRINUSE

1. The Process is Actually Running (and You Didn’t Know It)

  • Diagnosis: Use ss -tulnp | grep :<port_number> or netstat -tulnp | grep :<port_number>. Replace <port_number> with the port causing the error (e.g., 8080). This command will show you which process is listening on that port.

    ss -tulnp | grep :8080
    

    Example output: tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=1234,fd=3))

  • Fix: If the process is legitimate and you want to keep it running, you need to stop it gracefully before starting your new instance. Use kill <pid>, where <pid> is the Process ID found in the ss or netstat output.

    kill 1234
    

    If the process is stuck or unresponsive, you might need to use kill -9 <pid> for a forceful termination.

  • Why it works: This directly removes the existing process that is holding the port, freeing it up for your new application to bind.

2. Stale Socket Holding the Port

  • Diagnosis: Sometimes, a process might have crashed or been terminated abruptly, leaving its socket in a TIME_WAIT or CLOSE_WAIT state. ss -tulnp might not always show these as actively listening, but they can still prevent a new bind. You can check for connections in these states on the specific port.

    ss -tan state time-wait 'sport = :<port_number>'
    ss -tan state close-wait 'sport = :<port_number>'
    
  • Fix: The most common way to clear these stale sockets is to enable the SO_REUSEADDR socket option in your application’s code or, more commonly, by adjusting kernel parameters. For a temporary fix (until reboot), you can set net.ipv4.tcp_tw_reuse to 1.

    sudo sysctl -w net.ipv4.tcp_tw_reuse=1
    

    To make this persistent across reboots, add net.ipv4.tcp_tw_reuse = 1 to /etc/sysctl.conf (or a file in /etc/sysctl.d/) and run sudo sysctl -p.

  • Why it works: SO_REUSEADDR allows a socket to bind to a port that is in a TIME_WAIT state, effectively allowing a new socket to take over the address. tcp_tw_reuse specifically enables this for outgoing connections that are in TIME_WAIT.

3. Binding to the Wrong IP Address

  • Diagnosis: Your application might be configured to bind to a specific IP address (e.g., 127.0.0.1 for localhost) that is already in use by another process, while you intended to bind to 0.0.0.0 (all available interfaces). Check your application’s configuration for the bind_address or similar setting.

  • Fix: Change the application’s configuration to bind to 0.0.0.0 if you want it to be accessible from any network interface, or to a different specific IP address that is not in use. For example, in a Java application, this might be a system property or a configuration file entry.

  • Why it works: Binding to 0.0.0.0 tells the operating system to listen on all available network interfaces. If your application was previously bound to 127.0.0.1, and another process is using 127.0.0.1:<port_number>, your new application will fail. Changing to 0.0.0.0 will allow it to listen on all interfaces, including 127.0.0.1 if it’s not already fully occupied by another process on that specific IP.

4. Firewall Blocking (Less Common for EADDRINUSE, but Possible)

  • Diagnosis: While EADDRINUSE is typically about local binding, in some complex network setups (like Docker or Kubernetes), a port might appear in use due to internal networking rules or port mapping that are not immediately obvious. Check your firewall rules (iptables -L -n -v or ufw status verbose) and container networking configurations.

  • Fix: Adjust firewall rules or container port mappings to ensure the port is not being inadvertently claimed or blocked by another service or rule. This is highly dependent on your specific setup.

  • Why it works: If a firewall or network overlay is already using or mapping that port internally, it can present as EADDRINUSE to the application trying to bind. Correcting the network configuration resolves the conflict.

5. IPv6 vs. IPv4 Conflict

  • Diagnosis: If your application is configured to bind to an IPv4 address (e.g., 0.0.0.0:<port>), but an IPv6 process is already listening on the equivalent IPv6 address (:::<port>), you might see this error. Some systems, by default, will bind to both IPv4 and IPv6 if you specify 0.0.0.0. If you then try to bind explicitly to 0.0.0.0 again, or to :: (all IPv6 addresses), you might get EADDRINUSE. Check with ss -tulnp for both 0.0.0.0 and :::.

  • Fix: Explicitly configure your application to bind to either IPv4 (0.0.0.0) or IPv6 (:::) if you are encountering this. Alternatively, if you want to listen on both, ensure your application supports it or use a tool like socat to bridge them. For many applications, binding to 0.0.0.0 should handle both, but application-specific behavior can vary. If you’re seeing an IPv6 listener and want to use IPv4, try binding your application to 0.0.0.0 and verify it’s not already listening on :::.

  • Why it works: The operating system treats IPv4 and IPv6 addresses as distinct. If one is already bound, attempting to bind to the same port on the other family might succeed, but if the binding was for all addresses within a family (e.g., :: for IPv6), it can prevent a subsequent bind on a related address.

6. Application Configuration Errors

  • Diagnosis: Double-check your application’s configuration files, command-line arguments, or environment variables that specify the port and IP address it should bind to. A typo or an incorrect default value can lead to this error.

  • Fix: Correct the configuration to specify the desired port and IP address. Ensure the port number is within the valid range (1-65535) and not a reserved system port (0-1023) without appropriate privileges.

  • Why it works: This is a straightforward correction of the application’s intended network endpoint.

Once you’ve resolved the EADDRINUSE error, the next common issue you might encounter is ECONNREFUSED, which means your application started successfully but is not accepting connections on that port, or no other service is listening for incoming connections.

Want structured learning?

Take the full Linux & Systems Programming course →