Skip to content

doctor: add QUIC reachability check for the API port#819

Merged
evanphx merged 1 commit into
mirendev:mainfrom
jcasimir:jcasimir/doctor-quic-udp-check
May 22, 2026
Merged

doctor: add QUIC reachability check for the API port#819
evanphx merged 1 commit into
mirendev:mainfrom
jcasimir:jcasimir/doctor-quic-udp-check

Conversation

@jcasimir
Copy link
Copy Markdown
Contributor

Summary

Adds a [✓|✗] QUIC endpoint check to miren doctor server, alongside the existing HTTPS/HTTP checks.

The existing endpoint probes only cover TCP. If a host firewall (UFW, firewalld, cloud security group) allows TCP on the API port but not UDP — a common configuration when operators add 8443/tcp rules out of habit — every external miren deploy and miren cluster export-address silently fails with the client-side timeout error performing http request: timeout: no recent network activity. The server side shows zero observable signal: no errors, no warnings, no requests visible in miren logs system, because packets are dropped at netfilter INPUT before reaching the socket.

This is documented in docs/docs/firewall.md but is easy to miss, and the existing miren doctor server shows all green for HTTPS/HTTP while the actual API port is unreachable.

What it does

Adds checkQUIC(addr string) (bool, string) modeled on checkHTTPS / checkHTTP:

  • Dials QUIC with http3.NextProtoH3 (the same ALPN the real RPC server advertises in pkg/rpc/state.go), so a successful handshake also exercises the TLS path.
  • 5s handshake timeout; on context.DeadlineExceeded or the QUIC idle-timeout error, the detail message points directly at the most likely cause:
    [✗] QUIC   no response on udp/8443 (host firewall may be blocking inbound UDP)
    
  • On success:
    [✓] QUIC   handshake ok
    
  • IPv6-first, fallback to IPv4 for the local UDP socket — same pattern as cli/commands/cluster_add.go.

Usage

No CLI change. Just run as before:

miren doctor server

Output now includes the QUIC line in the Endpoints block.

Test plan

  • go build ./cmd/miren — compiles
  • go vet ./cli/commands/ — clean
  • golangci-lint run --timeout=10m ./cli/commands/... — 0 issues
  • Manual: run against a healthy local cluster → [✓] QUIC handshake ok
  • Manual: run against a cluster where UFW drops UDP 8443 → [✗] QUIC no response on udp/8443 (host firewall may be blocking inbound UDP)
  • Manual: run against a stopped miren (connection refused) — confirms the fallthrough error message is reasonable

No new tests in doctor_server_test.go — the existing checkHTTPS / checkHTTP helpers also have no tests and I didn't want to grow this PR's scope. Happy to add a table-driven test in a follow-up if maintainers want one.

Followups (out of scope here)

Things I considered and deliberately left out to keep the patch focused:

  • A startup banner on miren server start that mentions UDP is the API port, surfaced in journalctl.
  • Updates to showFixConnectivityHelp to specify lsof -i UDP:8443 (currently only suggests :443 TCP).
  • An optional UFW-rule check at miren server install time.

Happy to PR any of these separately if there's interest.

🤖 Generated with Claude Code

The existing HTTPS/HTTP probes in `miren doctor server` only cover TCP.
A host firewall (UFW, firewalld, cloud security group) that allows TCP
but not UDP on the API port — a common pitfall when operators add
`8443/tcp` rules out of habit — silently drops every API request while
passing the existing endpoint checks.

Adds a `[✓|✗] QUIC` endpoint to the same Endpoints block, modeled on
the existing checkHTTPS/checkHTTP helpers. Dials QUIC with the same
ALPN the real server advertises (http3.NextProtoH3) so a successful
handshake also exercises the TLS path. On timeout, the failure detail
points directly at the most likely cause.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jcasimir jcasimir requested a review from a team as a code owner May 22, 2026 18:22
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e631e8c6-2052-4f6a-b374-ea5df0d09645

📥 Commits

Reviewing files that changed from the base of the PR and between 10dd9b4 and 77c6aec.

📒 Files selected for processing (1)
  • cli/commands/doctor_server.go

📝 Walkthrough

Walkthrough

This PR extends the doctor server command with QUIC/UDP connectivity diagnostics for the cluster API. The implementation adds necessary imports for context and QUIC libraries, then integrates a new checkQUIC helper into the existing endpoint status reporting. The helper probes UDP port 8443 with a QUIC handshake using insecure TLS and HTTP/3 ALPN, enforces a 5-second timeout, and distinguishes firewall-blocking patterns (deadline exceeded) from other connection failures.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@evanphx
Copy link
Copy Markdown
Contributor

evanphx commented May 22, 2026

Thanks @jcasimir!

@evanphx evanphx merged commit 0611dce into mirendev:main May 22, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants