Skip to content

fix: guidance for port-conflict errors on 443 / service ports#364

Draft
gtsiolis wants to merge 2 commits into
mainfrom
pro-363-port-conflict-error-on-443-service-ports-gives-no-guidance
Draft

fix: guidance for port-conflict errors on 443 / service ports#364
gtsiolis wants to merge 2 commits into
mainfrom
pro-363-port-conflict-error-on-443-service-ports-gives-no-guidance

Conversation

@gtsiolis

@gtsiolis gtsiolis commented Jul 3, 2026

Copy link
Copy Markdown
Member

What

lstk start runs a pre-flight port check before starting the emulator. The primary edge port (4566) conflict path gave the user a next step (reconfigure the port); the extra-ports path (443 and the 4510–4559 service range) emitted a bare title + summary with no actions at all. Bart hit this on 443 (held by an unrelated sshd) and had no way to tell what was holding the port.

This routes both branches through the same emitPortInUseError helper so they render consistent guidance, and adds an OS-aware "identify the process" hint.

Before (extra-port conflict)

✗ Port 443 is already in use
  LocalStack requires this port. Free it before starting.

After (both 4566 and 443 / service ports)

✗ Port 443 already in use
  Another process is already using this port.
  ==> Identify the process using it: sudo lsof -i tcp:443
  ==> Or use another port in the configuration: …/config.toml

Details

  • internal/container/start.go — extra-ports branch now calls emitPortInUseError instead of emitting a bare ErrorEvent; the helper gained an "Identify the process using it" action.
  • internal/ports/ports.go — new InspectCommand(port): lsof -i tcp:<port> on macOS/Linux, netstat -ano | findstr :<port> on Windows. Privileged ports (<1024, e.g. 443) suggest sudo lsof, because lsof only lists other users' sockets under sudo — without it the hint returns nothing for a root-owned holder like sshd on 443, i.e. the reported case.
  • Neutral summary ("Another process is already using this port.") — deliberately does not claim it's a stray LocalStack instance (that case is already handled upstream by FindRunningByImage, and Bart's was sshd).
  • Tests: unit test for inspectCommand across OS/privileged-port branches; integration test TestStartCommandFailsWhenExtraPortInUse (binds 4510, since 443 is privileged and unbindable in a test).

Design choice, consistent with peers: this suggests a command rather than naming the process inline. Docker keeps its hot-path error generic and points to netstat in docs; ddev put process-naming in a separate opt-in port-diagnose command. Inline process-naming was intentionally kept out.

Scope / follow-ups

This closes the concrete defect (a guidance-less extra-ports error). It does not yet cover the case where the pre-flight localhost dial passes but Docker fails to bind at container start — that raw Bind for …: port is already allocated still surfaces with no guidance and is mis-bucketed as start_failed. That path (which a privileged-port / non-loopback-bindHost / TOCTOU conflict routes into) is the harder half and is tracked as a follow-up; this PR's green check does not mean that half is done.

Refs PRO-363.

gtsiolis added 2 commits July 3, 2026 18:31
The extra-port pre-flight check (443 and the 4510-4559 service range)
surfaced a bare "LocalStack requires this port" error with no next
steps, unlike the primary 4566 check which pointed at the config file.
Route both branches through emitPortInUseError so they render the same
guidance, and add an OS-aware "Identify the process using it" action
(lsof on macOS/Linux, netstat on Windows) so users can find what is
holding the port instead of guessing.

PRO-363
The "Identify the process using it" hint suggested a plain "lsof -i
tcp:<port>", but lsof only lists other users' sockets under sudo — so on
a privileged port such as 443 (commonly held by a root-owned process
like sshd) the suggested command returns nothing, the exact case that
prompted this. Suggest "sudo lsof" for ports below 1024 and keep plain
lsof for the 4510-4559 service range.

Also correct the extra-ports comment: a running LocalStack is already
ruled out by FindRunningByImage upstream, so a conflict here means an
unrelated process holds the port, not a second LocalStack instance.
@gtsiolis gtsiolis requested a review from a team as a code owner July 3, 2026 15:44
@gtsiolis gtsiolis self-assigned this Jul 3, 2026
@gtsiolis gtsiolis added semver: patch docs: skip Pull request does not require documentation changes labels Jul 3, 2026
@gtsiolis gtsiolis marked this pull request as draft July 3, 2026 15:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: skip Pull request does not require documentation changes semver: patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant