dnswatcher keeps running without its HTTP server when the listen port is in use #266

Open
opened 2026-10-13 12:32:08 +02:00 by clawbot · 0 comments
Collaborator

What is wrong. Server.Run logs http server error when ListenAndServe fails and returns; nothing stops the process. The watcher keeps checking and notifying, but the dashboard, /api/v1/status and the health check are unreachable for the life of the process.

Where (at e8b4006): internal/server/server.go, Run lines 153-165; New starts it with go srv.Run() in OnStart, so the error never reaches fx.

Scenario. A second copy is started on a host where the port is taken, or PORT names a privileged port and the process is not root. The log gets one error line; the process stays up and looks healthy to anything that watches the process rather than the port. In the image the HEALTHCHECK turns unhealthy, but the container keeps running. Confirmed by reading; not reproduced.

Correct. GO_HTTP_SERVER_CONVENTIONS.md's server cancels its context on a listen error so the process shuts down, and the README's reasoning for DNSWATCHER_TARGETS ("fails fast with a clear error message rather than running silently") applies here too. A listen failure stops the process with the error: bind the listener in OnStart (net.Listen, then Serve in the goroutine) so the failure fails startup, or call fx.Shutdowner from Run.

Done when: a listen failure stops dnswatcher with a non-zero exit and an error naming the address; a test starts the server on a port that is already bound and sees the failure.

Severity: minor

Model: fable-5-1

**What is wrong.** `Server.Run` logs `http server error` when `ListenAndServe` fails and returns; nothing stops the process. The watcher keeps checking and notifying, but the dashboard, `/api/v1/status` and the health check are unreachable for the life of the process. **Where** (at `e8b4006`): `internal/server/server.go`, `Run` lines 153-165; `New` starts it with `go srv.Run()` in `OnStart`, so the error never reaches fx. **Scenario.** A second copy is started on a host where the port is taken, or `PORT` names a privileged port and the process is not root. The log gets one error line; the process stays up and looks healthy to anything that watches the process rather than the port. In the image the `HEALTHCHECK` turns unhealthy, but the container keeps running. Confirmed by reading; not reproduced. **Correct.** `GO_HTTP_SERVER_CONVENTIONS.md`'s server cancels its context on a listen error so the process shuts down, and the README's reasoning for `DNSWATCHER_TARGETS` ("fails fast with a clear error message rather than running silently") applies here too. A listen failure stops the process with the error: bind the listener in `OnStart` (`net.Listen`, then `Serve` in the goroutine) so the failure fails startup, or call `fx.Shutdowner` from `Run`. **Done when:** a listen failure stops dnswatcher with a non-zero exit and an error naming the address; a test starts the server on a port that is already bound and sees the failure. Severity: minor Model: fable-5-1
clawbot added this to the 1.0 milestone 2026-10-13 12:32:08 +02:00
clawbot self-assigned this 2026-10-13 12:32:08 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/dnswatcher#266