How to Fix “Connection Refused” Error for Node.js Server on Ubuntu EC2 Instance


5 views

When setting up a Node.js web server on an Ubuntu EC2 instance, you might encounter the frustrating "Connection refused" error despite your server appearing to run correctly. This typically indicates a networking issue between your client and server.

First, confirm your Node.js server is actually running and listening on the correct port. SSH into your EC2 instance and run:

netstat -tulnp | grep node
# or alternatively:
ss -tulnp | grep node

You should see output similar to:

tcp   0   0 0.0.0.0:8080   0.0.0.0:*   LISTEN   1234/node

Amazon EC2 uses security groups as virtual firewalls. Ensure you've:

  1. Opened port 80 (HTTP) and 8080 in your security group
  2. Allowed traffic from 0.0.0.0/0 (or your specific IP range)

You can verify this in the AWS Console under EC2 > Security Groups.

From within your EC2 instance, test if the server responds locally:

curl http://localhost:8080

If this works but external connections fail, the issue is definitely network-related.

Your iptables port forwarding command needs adjustment. Try this instead:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

To make these changes persistent:

sudo apt-get install iptables-persistent
sudo netfilter-persistent save

Modify your Node.js server to listen on all network interfaces:

const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello World');
});

server.listen(8080, '0.0.0.0', () => {
  console.log('Server running on port 8080');
});

Ubuntu might be using UFW (Uncomplicated Firewall). Check its status:

sudo ufw status

If active, allow the necessary ports:

sudo ufw allow 80/tcp
sudo ufw allow 8080/tcp

After making these changes:

  1. Restart your Node.js server
  2. Check all firewall rules are properly configured
  3. Test from both local and external networks

Remember that AWS EC2 instances might take a few minutes for network changes to propagate completely.


When setting up a Node.js server on an EC2 Ubuntu instance, the "Connection refused" error typically indicates one of these fundamental issues:

  • Node.js server isn't bound to the correct network interface
  • Port forwarding rules aren't properly configured
  • Security groups or local firewall are blocking traffic
  • The application isn't actually listening on the expected port

First, ensure your Node.js application is properly configured to listen on all network interfaces (0.0.0.0) rather than just localhost:

const http = require('http');
const port = 8080;

const server = http.createServer((req, res) => {
  res.end('Hello from Node.js!');
});

// Critical: Bind to 0.0.0.0 instead of 127.0.0.1
server.listen(port, '0.0.0.0', () => {
  console.log(Server running at http://0.0.0.0:${port}/);
});

Check your AWS security group settings:

1. Inbound rules should allow:
   - HTTP (port 80) from 0.0.0.0/0
   - Custom TCP (port 8080) from 0.0.0.0/0
2. Outbound rules should allow all traffic

The current iptables rules might need adjustment. Here's a more comprehensive setup:

# Flush existing rules
iptables -F
iptables -t nat -F

# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Port forwarding from 80 to 8080
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

# Allow HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Save rules (Ubuntu specific)
iptables-save > /etc/iptables.rules

Run these commands to verify your setup:

# Check listening ports
sudo netstat -tulnp | grep node

# Check iptables rules
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v

# Test connectivity from another machine
telnet your-ec2-ip 80
telnet your-ec2-ip 8080

# Check AWS security groups
aws ec2 describe-security-groups --group-ids your-group-id

For production environments, consider using nginx:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

After making these changes, test with:

curl -v http://localhost:8080
curl -v http://your-ec2-ip:8080
curl -v http://your-ec2-ip

Each command should return your Node.js server response without connection refused errors.