When an application binds to localhost (127.0.0.1) instead of 0.0.0.0, other pods in the cluster cannot reach it -- even if a Kubernetes Service exposes the correct port. This topic explains why and provides two solutions.
Problem description
An application in the cluster listens on localhost, and other pods cannot access it through the Kubernetes Service.
Common localhost binding patterns:
| Language | Code |
|---|---|
| Go | net.Listen("tcp", "localhost:8080") |
| Node.js | http.createServer().listen(8080, "localhost") |
| Python | socket.socket().bind(("localhost", 8083)) |
Cause
Each pod in Kubernetes gets its own IP address. A Service routes traffic to this pod IP, not to localhost inside the pod. When an application binds to localhost, it only accepts connections on the loopback interface (127.0.0.1), which is scoped to the pod's own network namespace. Traffic arriving on the pod IP never reaches the application.
In an ASM-managed cluster, the Istio sidecar proxy adds another layer: it intercepts inbound traffic through iptables rules and forwards it to the application. If the application listens only on localhost, the sidecar proxy cannot deliver traffic to it because the forwarding targets the pod IP, not the loopback address.
Solutions
Two approaches are available:
| Approach | When to use |
|---|---|
| Change the bind address | You control the application source code |
| Configure a Sidecar resource | You cannot modify the application code |
Solution 1: Change the bind address
Update the application code to listen on 0.0.0.0 instead of localhost. This makes the application accept connections on all network interfaces, including the pod IP.
| Language | Before (localhost) | After (all interfaces) |
|---|---|---|
| Go | net.Listen("tcp", "localhost:8080") | net.Listen("tcp", "0.0.0.0:8080") |
| Node.js | http.createServer().listen(8080, "localhost") | http.createServer().listen(8080, "0.0.0.0") |
| Python | socket.socket().bind(("localhost", 8083)) | socket.socket().bind(("0.0.0.0", 8083)) |
After you deploy the updated code, verify that other pods can reach the application through the Service.
Solution 2: Configure a Sidecar resource
When changing the application code is not an option, create an Istio Sidecar resource that forwards inbound traffic to the localhost address. The sidecar proxy receives traffic on the Service port and redirects it to 127.0.0.1:<container-port> inside the pod.
Procedure
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose . On the page that appears, click Create from YAML.
Click Create from YAML.
On the Create page, select a namespace and a template, paste the following YAML configuration, and then click Create.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: localhost-access
namespace: <namespace>
spec:
ingress:
- defaultEndpoint: '127.0.0.1:<container-port>'
port:
name: tcp
number: <service-port>
protocol: TCP
workloadSelector:
labels:
<label-key>: <label-value>Replace the following placeholders with your actual values:
| Placeholder | Description | Example |
|---|---|---|
<namespace> | Namespace where the application is deployed | default |
<container-port> | Port on which the application listens on localhost | 8080 |
<service-port> | Port exposed by the Kubernetes Service | 80 |
<label-key>: <label-value> | Pod label that identifies the target workload | app: my-service |
The defaultEndpoint field tells the sidecar proxy where to forward inbound traffic. Setting it to 127.0.0.1:<container-port> routes requests to the loopback address, matching where the application already listens.
Verify the fix
After applying either solution, test cross-pod connectivity:
# From another pod, send a request to the application through its Service
kubectl exec -it <test-pod> -- curl http://<service-name>.<namespace>.svc.cluster.local:<service-port>A successful response confirms that the application is reachable from other pods.
If the request fails, check the sidecar proxy logs for forwarding errors:
kubectl logs <pod-name> -c istio-proxy