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 refusedThe 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 5000Analysis
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 listStep 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 interfacesStep 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 AnywhereStep 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_socketSolution
Fix 1: Start the Application
# If application is not running
$ python3 myapp.py &
# Or using systemd
$ sudo systemctl start myappFix 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 saveFix 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.ppFix 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=1Quick 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 APPCommon Causes Summary
| Error | Cause | Fix |
|---|---|---|
| Nothing listening | Application not started | Start application |
| Bound to 127.0.0.1 | Wrong bind address | Bind to 0.0.0.0 |
| Firewall blocking | iptables/ufw rule | Allow port through firewall |
| SELinux blocking | Policy too restrictive | Add SELinux exception |
| Address in use | Port already taken | Kill existing process |
Lessons Learned
- "Connection refused" means actively rejected - the port is not listening or blocked.
- Check
ss -tlnpfirst to see what's actually listening. - Verify bind address -
127.0.0.1vs0.0.0.0is a common issue. - Check firewall before application - firewall issues are easier to fix.
- 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.