ECONNREFUSED

Fix localhost:8080 Connection Refused on Linux

Localhost port 8080 refusing connections? Start with the service check, then the firewall, then the bind address. Real fixes for a classic pain.

Every Linux admin hits this wall eventually. You run your web app, type http://localhost:8080 into the browser, and get a blank page or an error that says something like connection refused or ECONNREFUSED. Don't panic. Nine times out of ten it's one of three things, and they're all easy to fix.

I had a client last month whose Jenkins was down. Turned out the service just died after a power blip, and the machine rebooted without starting it. Simple restart, done. But I've also seen cases where the service was running fine, just listening on the wrong IP — that wasted a solid hour before I checked the bind address.

Here's the troubleshooting flow. Do these in order. Stop when it works.

The 30-Second Fix: Is the Service Actually Running?

Sounds dumb, but you'd be surprised how often the app just crashed or never started. On systemd systems (Ubuntu 16.04+, Debian 8+, Fedora, CentOS 7+), check with:

systemctl status your-service-name

If you don't know the service name, look for anything listening on 8080:

ss -tlnp | grep 8080

If that returns nothing, nothing is listening. Then try starting the service:

sudo systemctl start your-service-name

If it's not a systemd service — maybe you ran it manually in a terminal — check if that terminal is still open. I've lost count of how many times I've closed a SSH session and killed my own dev server.

If the service is running but ss still shows nothing on port 8080, move on to the next step.

The 5-Minute Fix: Firewall Blocking Localhost

Firewalls usually don't block localhost, but misconfigurations happen. If you're using UFW (Ubuntu's default), check the rules:

sudo ufw status

If you see 8080/tcp DENY or nothing about 8080, add an allow rule:

sudo ufw allow 8080/tcp

For firewalld (Fedora, RHEL):

sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

But here's the thing — even with a firewall, connecting to 127.0.0.1 often bypasses iptables. If you're getting connection refused on localhost specifically, the firewall is rarely the culprit. Unless you've got some custom chain that even blocks loopback. That's rare, but I've seen it. So rule it out, then move on.

The 15-Minute Fix: Service Listening on the Wrong Address

This is the sneaky one. Your service is running, firewall is open, but you still get connection refused. Check what address it's bound to:

ss -tlnp | grep 8080

Look at the Local Address column. If it says 0.0.0.0:8080 or :::8080, it's listening on all interfaces, and localhost should work. But if it says something like 192.168.1.100:8080 or a specific public IP, then it's not listening on loopback, so localhost:8080 will refuse the connection.

Why does this happen? Default configs in many apps bind to 0.0.0.0 or to a specific interface. Some apps like Jenkins, by default, bind to 0.0.0.0, which is fine. But others like Flask or Django dev servers might bind to 127.0.0.1 by default, which is also fine. The problem is when someone set a custom bind address to a specific NIC, and then the NIC changes (like after a reboot or moving from Wi-Fi to Ethernet).

To fix it, you need to change the bind address in the app's config. For example, in Jenkins, edit /etc/default/jenkins and set:

JENKINS_LISTEN_ADDRESS="0.0.0.0"

For a Node.js app, look for the HOST environment variable or the listen call. In Python's Flask, you'd do:

app.run(host='0.0.0.0', port=8080)

But careful — binding to 0.0.0.0 exposes the port to the network. If you only need localhost, bind to 127.0.0.1. That's the safest.

If you can't change the app config, you can use socat to forward localhost traffic to the bound address:

socat TCP-LISTEN:8080,fork TCP:192.168.1.100:8080 &

That's a hack, but it works in a pinch.

One More Thing: SELinux or AppArmor

If none of that worked, especially on Fedora or RHEL, SELinux might be blocking it. Check for denials:

sudo grep "denied" /var/log/audit/audit.log | tail

Or on Ubuntu with AppArmor, check dmesg for AppArmor messages. I've had a custom service get blocked by SELinux because it tried to bind to a non-standard port. The fix is usually sudo setsebool -P httpd_can_network_connect 1 if it's Apache, or create a custom policy. That's a deeper rabbit hole, but knowing where to look saves you hours.

Still Stuck?

If you've gone through all that and it's still refusing, check for another service already using 8080. You can't bind two services to the same port. Use ss -tlnp | grep 8080 to see if something else owns it. If it's occupied, you'll need to either stop that service or change your app's port.

Also, don't forget IPv6. Some apps listen on :: but not on IPv4, and vice versa. If localhost resolves to ::1 first, but your app only listens on IPv4, you'll get refused. Try curl http://127.0.0.1:8080 vs curl http://[::1]:8080 to see which one works.

That's the whole flow. Ninety percent of the time, the first two fixes solve it. The third is the tricky one that people miss. And now you know it.

Related Errors in Linux & Unix
Module is unknown PAM Module Configuration Error: Fix 'Module is unknown' E: dpkg was interrupted Fix dpkg Interrupted Error: Run dpkg --configure -a Fix GParted Locked Partition Resize Error E: Could not calculate upgrade Debian/Ubuntu: Fix 'Could Not Calculate Upgrade' Error

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.