troubleshooting2025-05-18·8·60/348

Resolving TCP/IP Socket Connection Refused Errors

Comprehensive guide to diagnosing and fixing 'Connection refused' errors on Linux, including listening ports, firewall rules, and application configuration.

Resolving TCP/IP Socket Connection Refused Errors

"Connection refused" means the TCP stack actively rejected your connection attempt. Unlike a timeout, this indicates the server is reachable but not accepting connections on the requested port. This guide covers systematic diagnosis.

Environment

  • OS: Ubuntu 22.04 LTS
  • Application: Custom TCP server on port 5000
  • Client: Same machine (localhost)
$ nc -zv localhost 5000
nc: connect to localhost (127.0.0.1) port 5000 (tcp) failed: Connection refused

The Problem

# Test connection
$ curl -v http://localhost:5000
*   Trying 127.0.0.1:5000...
* connect to 127.0.0.1 port 5000 failed: Connection refused
* Failed to connect to localhost port 5000: Connection refused

# Check if anything is listening
$ ss -tlnp | grep :5000
# No output - nothing is listening on port 5000

Analysis

Step 1: Check Listening Ports

# Check all listening TCP ports
$ ss -tlnp
State      Recv-Q Send-Q  Local Address:Port   Peer Address:Port  Process
LISTEN     0      128     0.0.0.0:22           0.0.0.0:*          users:(("sshd",pid=1234,fd=3))
LISTEN     0      128     0.0.0.0:80           0.0.0.0:*          users:(("nginx",pid=5678,fd=6))
LISTEN     0      128     0.0.0.0:443          0.0.0.0:*          users:(("nginx",pid=5678,fd=7))

# Port 5000 is NOT in the list

Step 2: Check Application Status

# Check if application is running
$ ps aux | grep myapp
joel     12345  0.0  0.1  24576  8904 pts/0    S+   10:00   0:00 python3 myapp.py

# Check if it's bound to the right address
$ sudo lsof -i :5000
# No output - application is running but not listening

# Check application logs
$ tail -f /var/log/myapp.log
2025-05-18 10:00:00 ERROR: Address already in use
2025-05-18 10:00:01 WARNING: Retrying binding to port 5000...

Step 3: Check for Address Binding

# Check if bound to wrong interface
$ ss -tlnp | grep :5000
LISTEN  0  128  127.0.0.1:5000  0.0.0.0:*  users:(("myapp",pid=12345,fd=6))
# Bound to 127.0.0.1 only - not accessible from outside

# Check all interfaces
$ ss -tlnp
LISTEN  0  128  0.0.0.0:5000  0.0.0.0:*  users:(("myapp",pid=12345,fd=6))
# Bound to 0.0.0.0 - accessible on all interfaces

Step 4: Check Firewall Rules

# Check if firewall is blocking
$ sudo iptables -L -n | grep 5000
Chain INPUT (policy DROP)
DROP  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:5000

# Check ufw
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
5000/tcp                   DENY IN     Anywhere

Step 5: Check SELinux

# Check if SELinux is blocking
$ sudo ausearch -m AVC --recent | grep 5000
type=AVC msg=audit(...): avc:  denied  { name_bind } for  
    pid=12345 comm="myapp" 
    scontext=unconfined_u:unconfined_t:s0 
    tcontext=system_u:object_r:unreserved_port_t:s0 
    tclass=tcp_socket

Solution

Fix 1: Start the Application

# If application is not running
$ python3 myapp.py &

# Or using systemd
$ sudo systemctl start myapp

Fix 2: Fix Address Binding

# Python - bind to all interfaces
import socket

# BAD: Only accessible locally
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 5000))

# GOOD: Accessible on all interfaces
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 5000))
// Node.js - bind to all interfaces
const server = net.createServer();

// BAD: Only accessible locally
server.listen(5000, '127.0.0.1');

// GOOD: Accessible on all interfaces
server.listen(5000, '0.0.0.0');

Fix 3: Allow Port Through Firewall

# Using ufw
$ sudo ufw allow 5000/tcp

# Using iptables
$ sudo iptables -I INPUT -p tcp --dport 5000 -j ACCEPT
$ sudo service iptables save

Fix 4: Fix SELinux Policy

# Allow binding to unreserved port
$ sudo setsebool -P allow_user_execs 1

# Or create custom policy
$ sudo ausearch -m AVC --recent | audit2allow -M myapp_policy
$ sudo semodule -i myapp_policy.pp

Fix 5: Fix Address Already in Use

# Find what's using the port
$ sudo lsof -i :5000
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
myapp    1234   joel    6u  IPv4  45678      0t0  TCP *:5000 (LISTEN)

# Kill the process
$ sudo kill 1234

# Or wait for TIME_WAIT to clear
$ sudo sysctl -w net.ipv4.tcp_tw_reuse=1

Quick Diagnostic Commands

# Check what's listening
$ ss -tlnp | grep :PORT

# Check if port is reachable
$ nc -zv HOST PORT

# Check firewall
$ sudo iptables -L -n | grep PORT
$ sudo ufw status | grep PORT

# Check application
$ ps aux | grep APP

Common Causes Summary

ErrorCauseFix
Nothing listeningApplication not startedStart application
Bound to 127.0.0.1Wrong bind addressBind to 0.0.0.0
Firewall blockingiptables/ufw ruleAllow port through firewall
SELinux blockingPolicy too restrictiveAdd SELinux exception
Address in usePort already takenKill existing process

Lessons Learned

  1. "Connection refused" means actively rejected - the port is not listening or blocked.
  2. Check ss -tlnp first to see what's actually listening.
  3. Verify bind address - 127.0.0.1 vs 0.0.0.0 is a common issue.
  4. Check firewall before application - firewall issues are easier to fix.
  5. Test locally first - if localhost works but remote doesn't, it's a network/firewall issue.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.