Skip to content

[repo-health] Low: Default port 4317 conflicts with IANA-assigned OpenTelemetry OTLP/gRPC port #13

Description

@Liohtml

Summary

agentbox defaults the Observer dashboard to port 4317, which is the IANA-assigned port for OpenTelemetry OTLP/gRPC (registered November 2020). On any developer machine that runs an OTel collector, Jaeger, Grafana Agent, or similar observability stack, port 4317 will already be bound — causing agentbox up to fail with a cryptic Docker port-binding error at runtime rather than a clear message.

Category

Bug / Usability

Severity

Low

Location

  • File: src/types.ts, line 83 — observerPort: 4317
  • File: assets/observer.mjs, line 16 — const PORT = Number(process.env.OBSERVER_PORT || 4317)
  • File: README.md — all references to http://localhost:4317

Details

Port 4317 was assigned by IANA to OTLP/gRPC in 2020 and is the default port for:

  • OpenTelemetry Collector (gRPC receiver)
  • Grafana Agent / Alloy (OTLP ingestion)
  • Jaeger all-in-one (OTLP endpoint)
  • Datadog Agent (when OTLP ingestion is enabled)

A developer working on any instrumented service will commonly have one of these listening on 4317. When they run agentbox up, Docker's -p 127.0.0.1:4317:4317 binding fails silently (Docker prints a port-in-use error but agentbox doesn't surface a clear "choose a different port" message).

The --port flag exists as the workaround, but this is not discoverable and the conflict is not documented.

Suggested Fix

Two complementary changes:

  1. Change the default port to something outside common IANA-assigned developer ranges. Port 4320 or 4321 are unassigned and close enough to the current default to feel familiar:
// src/types.ts
observerPort: 4320,
  1. Add a port-in-use check in cmdDoctor and optionally cmdUp:
import { createServer } from "node:net";
function isPortFree(port: number): Promise<boolean> {
  return new Promise((resolve) => {
    const s = createServer().listen(port, "127.0.0.1");
    s.on("listening", () => { s.close(); resolve(true); });
    s.on("error", () => resolve(false));
  });
}
// In cmdDoctor:
const portFree = await safe(() => isPortFree(config.observerPort), false);
line(portFree, `Observer port ${config.observerPort} is free`);
if (!portFree) hardFailure = true;

Effort Estimate

15 min


Automated finding by repo-health-agent v1.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions