## TL;DR

"Connection refused" from the OpenTelemetry collector means nothing is listening on the receiver port: the receiver isnt enabled in the config, the port is wrong, or a firewall sits in the way. Check the config first, then the port. The fix is usually one line in the collector config, not a network problem.

## Error / query

```text
OpenTelemetry collector "connection refused" fix
```

Your app cant reach the collector and every export fails with connection refused. The telemetry isnt flowing.

## Use this skill when

- OTel exporters fail with "connection refused"
- spans or metrics arent arriving at the collector
- you just deployed the collector and nothing connects
- youre debugging OTLP receiver connectivity

## Not for this skill when

- the collector receives data but drops it (a pipeline/processor problem)
- you need sampling or tail-based sampling config (pipeline tuning)
- the error is about TLS certificates, not refused connections (different fix)

## Steps

### 1. Confirm the receiver is enabled in the collector config

The collector only listens on what its config enables. If the OTLP receiver isnt in the config, nothing listens on 4317/4318.

```bash
grep -A5 "receivers:" /etc/otelcol/config.yaml | head -20
```

Expected: you see the `otlp` receiver listed under receivers. If its missing, thats the bug; add it.

### 2. Verify the port is actually listening on the collector host

Config says enabled, but is the socket open? Check on the collector host itself.

```bash
ss -tlnp | grep -E "4317|4318" || echo "nothing listening on OTLP ports"
```

Expected: a listening socket on 4317 (gRPC) or 4318 (HTTP). "Nothing listening" means the collector didnt start the receiver; check the collector logs next.

### 3. Test the connection from the application host

The port may listen locally but be unreachable from where the app runs. Test from the app host, not the collector host.

```bash
nc -zv [collector-host] 4317
```

Expected: connection succeeded. A refusal here with a listening port in step 2 means a firewall between the hosts.

### 4. Fix the config and restart the collector

Add the missing receiver (or fix the port), restart, and confirm the socket appears.

```bash
systemctl restart otelcol
sleep 3
ss -tlnp | grep 4317
```

Expected: the port shows as listening after restart, and spans start arriving within a minute.

## Variant phrasings

### otel collector cannot connect

Same fix: the four checks above cover every common cause of collector connection failures.

### opentelemetry exporter connection refused

Same fix: from the exporters side it looks like a network error, but the cause is usually the collector config. Start at step 1.

### otlp receiver not working

Same fix: "not working" with connection refused specifically means the receiver isnt listening. Steps 1 and 2 find it.

## Why it happens

The collector is config-driven: no receiver stanza, no listener. People assume installing the collector means its listening, but the default config may not enable the receiver they need, or they edited the config without restarting. Connection refused is the OS telling you nobody is home on that port, which is refreshingly honest as errors go.

## Edge cases and pitfalls

- Docker networking: the app container needs the host or service name, not a container IP that changes on restart.
- TLS mismatch: receiver expects TLS but the exporter sends plaintext (or vice versa). The error can masquerade as a refusal.
- Port already in use: another process grabbed 4317. Check with `ss` before assuming the collector owns it.
- Config edited but collector not restarted: the collector reads config at startup. Edit, restart, verify, in that order.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_aWyfLcOfAlhdNihav_kFfw
