Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenTelemetry By James Joyner IV · · 9 min read

OpenTelemetry Error Guide: 'bind: cannot assign requested address' — Fix Collector Listen Address

Quick answer

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
Free toolkit

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 address naming a specific IP, not 0.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 refused because nothing ever listened.
  • Started after moving the Collector to a new node, container, or network namespace.
  • otelcol-contrib validate passes (the YAML is valid) but runtime bind fails.

Common Root Causes

  • Endpoint hard-coded to a non-local IP — the receiver endpoint uses 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.x or secondary loopback address that was never configured with ip 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 endpoint with a hard-coded IP between hosts, containers, or nodes without re-checking ip 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.0 and 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: EADDRNOTAVAIL is a wrong-IP problem, EADDRINUSE is 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.

Free download · 368-page PDF

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.