OpenTelemetry Error Guide: 'bind: cannot assign requested address' — Fix Collector Listen Address
Fix 'listen tcp 10.0.0.9:4317: bind: cannot assign requested address' when the OTel Collector receiver binds an IP not on the host: use 0.0.0.0.
- #opentelemetry
- #observability
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
This error appears at startup when the Collector tries to bind a receiver to a specific IP address that does not exist on the host. The kernel rejects the bind() syscall because no local interface owns that address, and the Collector refuses to start:
Error: cannot start pipelines: listen tcp 10.0.0.9:4317: bind: cannot assign requested address
2026/07/12 14:22:10 collector server run finished with error: listen tcp 10.0.0.9:4317: bind: cannot assign requested address
bind: cannot assign requested address (EADDRNOTAVAIL) is not the same as address already in use (EADDRINUSE). “In use” means the port is taken by another process; “cannot assign requested address” means the IP you asked to bind is not configured on any local interface. The Collector never begins listening, so every exporter targeting it fails with connection refused.
Symptoms
- The Collector exits immediately at startup and never opens its OTLP ports.
- Logs show
bind: cannot assign requested addressnaming a specific IP, not0.0.0.0. - The named IP is a service, VIP, or another node’s address — not one on this host.
- Clients pointed at the Collector get
connection refusedbecause nothing ever listened. - Started after moving the Collector to a new node, container, or network namespace.
otelcol-contrib validatepasses (the YAML is valid) but runtime bind fails.
Common Root Causes
- Endpoint hard-coded to a non-local IP — the receiver
endpointuses an address that belonged to the old host or a load balancer, not this machine. - Container networking mismatch — inside a container the host’s IP is not present on the pod/container interface, so binding it fails.
- VIP or floating IP not attached — the receiver binds a keepalived/EIP virtual IP that has not been assigned to this node.
- IPv6 address on an IPv4-only interface (or vice versa) — the family of the configured address is not available.
- Loopback alias missing — binding a specific
127.xor secondary loopback address that was never configured withip addr add. - Node reschedule — a Kubernetes pod moved to a node whose IP differs from the one baked into the config.
Diagnostic Workflow
List the addresses that actually exist on the host and compare them to the one in the error. If the failing IP is not in this list, that is the whole problem:
# What IPs does this host actually own?
ip -brief addr show
# Confirm the specific address is (not) present
ip addr show | grep 10.0.0.9 || echo "10.0.0.9 is NOT on this host"
Inspect the receiver endpoint values in the Collector config — a specific IP here is the usual culprit:
grep -n 'endpoint' /etc/otelcol-contrib/config.yaml
The robust fix for almost every deployment is to bind 0.0.0.0 (all IPv4 interfaces) so the Collector listens regardless of which address the host has:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
If you must bind a single specific interface (for example to restrict exposure), use an address the host genuinely owns — take it from ip -brief addr show rather than hard-coding a VIP:
receivers:
otlp:
protocols:
grpc:
endpoint: 10.0.0.11:4317 # an IP confirmed present on THIS host
Validate the config and restart, then confirm the ports are actually bound:
otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
systemctl restart otelcol-contrib
ss -ltnp | grep -E '4317|4318'
journalctl -u otelcol-contrib --since '2 min ago' | grep -i 'bind\|listen'
Example Root Cause Analysis
A Collector config was copied verbatim from a bare-metal host, where the receiver was pinned to that machine’s static IP 10.0.0.9:4317, into a Kubernetes DaemonSet. On the bare-metal host the bind succeeded because 10.0.0.9 was a real interface address. Inside the pod, however, the container network namespace only had the pod IP (something in 10.244.x.x), so 10.0.0.9 did not exist locally and the Collector crash-looped with listen tcp 10.0.0.9:4317: bind: cannot assign requested address.
The fix was to change the receiver endpoint from the hard-coded host IP to 0.0.0.0:4317, which binds every interface the container has, and to expose the port through the Service instead of relying on a fixed node address. After the change the DaemonSet pods started cleanly, ss -ltnp showed 0.0.0.0:4317 bound in each pod, and application exporters connected without the downstream connection refused they had been seeing.
Prevention Best Practices
- Default receiver endpoints to
0.0.0.0(or[::]for IPv6) so binding does not depend on a specific host IP. - Never copy a receiver
endpointwith a hard-coded IP between hosts, containers, or nodes without re-checkingip addr. - If you pin a specific interface for security, template the address from the host’s real IP via config management, not a literal.
- For VIPs/floating IPs, ensure the address is attached to the node (keepalived/EIP) before the Collector starts, or bind
0.0.0.0and restrict at the firewall. - Add a startup smoke test (
ss -ltnp | grep 4317) so a failed bind is caught immediately rather than as downstream refusals. - Keep the difference clear in runbooks:
EADDRNOTAVAILis a wrong-IP problem,EADDRINUSEis a port-conflict problem.
Quick Command Reference
# List the IPs this host actually owns
ip -brief addr show
# Check whether the failing address exists locally
ip addr show | grep 10.0.0.9 || echo "not on this host"
# Find hard-coded endpoints in the config
grep -n 'endpoint' /etc/otelcol-contrib/config.yaml
# Validate config, then confirm the ports are bound after restart
otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
ss -ltnp | grep -E '4317|4318'
Conclusion
bind: cannot assign requested address means the Collector was told to listen on an IP that no local interface owns — a host-specific address carried into a container, a moved node, or an unattached VIP. It is distinct from address already in use, which is a port conflict. Bind receivers to 0.0.0.0 so listening no longer depends on which address the host happens to have, and reserve specific-IP binds for cases where you have confirmed the address is present with ip addr show.
Related
- OpenTelemetry Error Guide: ‘address already in use’
- OpenTelemetry Error Guide: ‘connection refused’ to the Collector
- OpenTelemetry Error Guide: ‘failed to parse config’
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.