Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

Relationships

#1748 wss:// direct to serve's own TLS listener still fails on 20260817 — client ALPN lands on h2, WS-over-h2 unimplemented (follow-up to #1363)

Opened by psftw · 8/20/2026

Follow-up to #1363 (closed as duplicate of #1345, fixed by PR #1941): confirming @dougschaefer's 2026-07-29 finding that the direct-listener case survives that fix, now on 20260817.010424.0-sha.21133ea1 (client and serve).

Setup: serve on a Debian 13 guest with --host <wg-ip> --port 4000 --auth-mode token --cert-file … --key-file …, self-signed EC P-256, SAN IP:<wg-ip>; client on the operator machine over WireGuard (0.2 ms RTT, verified handshake). No proxy anywhere.

$ swamp access token list --server wss://<wg-ip>:4000 --json
{ "error": "Could not connect to wss://<wg-ip>:4000/: NetworkError:
  failed to connect to WebSocket: HTTP/2 not supported by this client" }

--server https://… is normalized back to wss:// by the client and fails identically.

The server side is fine:

$ echo | openssl s_client -connect <wg-ip>:4000 | grep -iE 'alpn|protocol'
No ALPN negotiated                      # no-ALPN ClientHello → accepted
$ echo | openssl s_client -connect <wg-ip>:4000 -alpn http/1.1 | grep ALPN
ALPN protocol: http/1.1                 # http/1.1 honored when offered
$ curl -sk --http1.1 -o /dev/null -w '%{http_code} %{http_version}\n' https://<wg-ip>:4000/
200 1.1

So the failure is purely client-side: the ClientHello lands the connection on h2, and WebSocket-over-h2 (RFC 8441 extended CONNECT) is unimplemented. One attribution detail beyond the earlier reports: the HTTP/2 not supported by this client string comes from deno_fetch (found via strings on the binary) — Deno's HTTP client performing the WS handshake, which is where an http/1.1 ALPN offer or fallback would need to land.

Since off-loopback binding requires TLS and serve exposes no ALPN/HTTP-version flag, a TLS-enabled serve remains unreachable by its own client.

Workaround in use: serve bound to loopback plain ws, fronted by a TCP passthrough (systemd-socket-proxyd) on the private address; WireGuard provides transport crypto and token auth the application layer. The TLS-listener configuration is preserved in our history and can be re-provisioned to test a diagnostic build.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/20/2026, 2:16:44 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.