Fixing the 'dial tcp: connect: connection refused' Error in Go

beginner🔷 Go2026-06-10| Go (Golang) applications running on Linux, macOS, or Windows, typically involving PostgreSQL, MySQL, Redis, or microservices.

Error Message

dial tcp 127.0.0.1:5432: connect: connection refused
#golang#networking#docker#postgresql#troubleshooting

Decoding the ErrorYou hit go run main.go and instead of a running app, you get a wall of text ending in connection refused. It is a frustrating moment, but the message is actually quite specific. Go's net package throws this when your code successfully finds the target IP (like 127.0.0.1), but the operating system at that destination actively rejects the request on the port you chose (like 5432).

Think of it like dialing a valid phone number, but the person on the other end immediately hangs up because they aren't taking calls on that specific line.

Why Connections FailMost developers run into this for one of four reasons:

  • The service is ghosting you: Your database (PostgreSQL, Redis, etc.) isn't actually running.- Wrong door: You’re trying to connect to port 5432, but the service is actually listening on 5433 or 8080.- Isolation: The service is running but only listens for local traffic, while you are trying to reach it from a different network interface.- The Docker Trap: Your Go app is in a container and thinks localhost is itself, rather than your computer.## Step-by-Step Fixes### 1. Verify the Service StatusFirst, make sure the target service is actually alive. If you're using PostgreSQL on port 5432, check its status immediately. A service that crashed or never started is the most common culprit.
# On Linux (systemd) systemctl status postgresql  # On macOS (Homebrew) brew services list

If the status says inactive or stopped, fire it up. If it’s not installed, that’s your first hurdle.

2. Audit Your Ports and AddressesDoes your Go connection string actually match reality? A standard connection attempt in Go looks like this:

// Attempting a TCP handshake conn, err := net.Dial("tcp", "127.0.0.1:5432") if err != nil {     log.Fatalf("Connection failed: %v", err) }

Check if anything is actually listening on that port using lsof. If the output is empty, no service is claiming that port.

# Look for listeners on port 5432 sudo lsof -i :5432 # Or use netstat for a quick check netstat -tuln | grep 5432

3. Solve the Docker 'Localhost' MysteryThis is the #1 mistake in modern development. When your Go code runs inside a Docker container, 127.0.0.1 refers to the container's internal loopback, not your host machine. Your database isn't inside that container, so the connection fails instantly.

Update your connection string based on your OS:

  • macOS and Windows: Swap 127.0.0.1 for host.docker.internal.- Linux: Use the gateway IP (usually 172.17.0.1) or run the container with --network="host" to share the host's networking stack.### 4. Check the Bind AddressSometimes a service is shy. It might be configured to listen only on 127.0.0.1, which means it will ignore any requests coming from an external IP or a Docker bridge. Look at your postgresql.conf or similar config file:
# postgresql.conf listen_addresses = 'localhost'  # Strict: only local apps can connect listen_addresses = '*'          # Open: allows connections from any interface

After changing this to '*', you must restart the service for the changes to take effect.

Verify the Fix in 5 SecondsDon't wait for your Go app to compile just to test a fix. Use nc (netcat) to see if the port is open and accepting traffic:

# Quick ping test nc -vz 127.0.0.1 5432

A successful connection returns: Connection to 127.0.0.1 port 5432 [tcp/postgresql] succeeded!. If it still says refused, the problem is with your firewall or the service configuration, not your Go code.

Pro-Tips for Stable Apps- Avoid Hardcoding: Use environment variables like DB_HOST=127.0.0.1. This lets you swap to a production URL without recompiling.- Implement Retries: Databases often take 5–10 seconds to fully initialize. Use a retry loop in Go to attempt the connection 3–5 times before giving up.- Wait-For-It: If using Docker Compose, use a depends_on health check to ensure the database is healthy before your Go binary starts.

Related Error Notes