127.0.0.1: the loopback address and localhost explained

127.0.0.1 is the IPv4 loopback address: it always means "this computer". Packets sent to it never reach a network card; the operating system hands them straight back to a program on the same machine. localhost is the name for it, so http://localhost:8080 and http://127.0.0.1:8080 normally reach the same server. Every device has its own 127.0.0.1, which is why your phone can't open your laptop's.

127.0.0.1, localhost, ::1 and 0.0.0.0

AddressWhat it isUse it to
127.0.0.1IPv4 loopbackReach a server on this machine
127.0.0.0/8Whole loopback block (127.0.0.1 to 127.255.255.254)Run several local services on separate IPs
::1IPv6 loopbackSame as 127.0.0.1, over IPv6
localhostHostname for the loopbackUsually resolves to both 127.0.0.1 and ::1
0.0.0.0"All interfaces" when a server bindsMake a server reachable from other devices
192.168.x.x, 10.x.x.xYour LAN addressReach this machine from another device on the network

localhost is defined in your hosts file (/etc/hosts on macOS and Linux, C:\Windows\System32\drivers\etc\hosts on Windows), and modern browsers and resolvers always treat it as loopback.

Why "127.0.0.1 refused to connect"

ERR_CONNECTION_REFUSED on 127.0.0.1 means your machine answered, but no program is listening on that port.

  1. Include the port. http://127.0.0.1 means port 80. Dev servers use 3000, 5173, 8000, 8080 and so on.
  2. Start the server and read the URL it prints.
  3. IPv4 vs IPv6. If localhost works but 127.0.0.1 doesn't (or the reverse), the server is bound to only ::1 or only 127.0.0.1. Bind it explicitly to the one you use, or to 0.0.0.0.
  4. Check what's listening:
# macOS / Linux
lsof -iTCP -sTCP:LISTEN -n -P
# Windows
netstat -ano | findstr LISTENING

Free a port with kill -9 $(lsof -ti :PORT) on macOS and Linux, or taskkill /PID <pid> /F on Windows.

Docker, VMs and emulators

127.0.0.1 is local to each network namespace, which trips people up:

  • Inside a Docker container, 127.0.0.1 is the container, not your computer. To reach a service on the host, use host.docker.internal (Docker Desktop, or --add-host=host.docker.internal:host-gateway on Linux).
  • A server inside a container must bind 0.0.0.0, not 127.0.0.1, or published ports (-p 8080:8080) won't reach it.
  • The Android emulator reaches your computer at 10.0.2.2; its own 127.0.0.1 is the emulated phone.
  • WSL2 forwards localhost to Windows in most setups. If not, use the WSL VM's IP.

Binding to 127.0.0.1 vs 0.0.0.0

Binding a server to 127.0.0.1 is the safe default: only programs on the same machine can connect. Django, Flask, Vite, Jupyter, Ollama and PostgreSQL all start this way. Bind to 0.0.0.0 only when other devices need to connect, and only on a network you trust. Then open http://YOUR-LAN-IP:PORT from the other device, never 127.0.0.1.

127.0.0.1 and webhooks

A webhook provider can't deliver to http://127.0.0.1:3000/webhooks. To Stripe or GitHub, 127.0.0.1 is their own server, and most providers reject loopback and private addresses outright. Your local handler needs a public URL that forwards to it:

relay forward --bucket my-app http://127.0.0.1:3000/webhooks

The relay agent connects outbound, so there's no router or firewall change, and the bucket's public URL stays the same between sessions. To share a whole local site rather than just receive webhooks, relay connect --name my-app http://127.0.0.1:3000 gives the port a public HTTPS URL. See receive webhooks on localhost.

Frequently asked questions

What is 127.0.0.1?

127.0.0.1 is the IPv4 loopback address. Traffic sent to it never leaves your computer; the operating system delivers it straight back to a program on the same machine. Every computer has its own 127.0.0.1.

Is 127.0.0.1 the same as localhost?

Almost. localhost is a hostname that normally resolves to 127.0.0.1 and to the IPv6 loopback ::1. If a server listens only on IPv4 or only on IPv6, one of localhost and 127.0.0.1 can work while the other is refused.

Why does 127.0.0.1 refuse to connect?

No program is listening on that port on your machine. Start the server, check which port it actually uses, and include the port in the address, for example http://127.0.0.1:8080.

What is the difference between 127.0.0.1 and 0.0.0.0?

A server bound to 127.0.0.1 only accepts connections from the same machine. A server bound to 0.0.0.0 listens on every network interface, so other devices on the network can reach it too. 0.0.0.0 is a bind address, not an address you browse to.

Can a webhook be sent to 127.0.0.1?

No. A webhook provider sending to 127.0.0.1 would be sending to its own server, and most providers reject loopback URLs outright. To receive webhooks on your machine, give the provider a public URL that forwards to your local port, for example with a webhook relay or a tunnel.