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

Relationships

#1548 serve reload and model edit timeout over --server in Kubernetes

Opened by stack72 · 8/7/2026

Description

Users running swamp serve on Kubernetes report that swamp serve reload --server and swamp model edit --server timeout with no server-side logs produced. Other --server commands (e.g. model get, model list) work fine.

Environment

  • Kubernetes with nginx ingress controller
  • OAuth auth mode, user is an admin
  • Server started with --hot-reload
  • Repo volume (/repo) and home directory (/home/[REDACTED]/.swamp) on different volume mounts (separate PVCs)
  • Ingress proxy timeouts are set to 3600s — not the cause

Investigation Summary

Code analysis

The handleServeReload handler (admin_handlers.ts:1716) and handleModelEdit handler (model_handlers.ts:1369) both have comprehensive try/catch blocks that always send a response frame. Every branch — auth failure, hot-reload disabled, success, error — calls send() or sendError(). The RPC path for serve reload never uses SIGHUP; it calls performServeReload() directly in-process via WebSocket RPC.

What "no logs" tells us

handleServeReload logs "Extension reload requested by ..." immediately after the auth check passes (line 1742). No logs means either:

  1. The request never reaches the handler
  2. The auth check at authorizeOrReject fails — but this always calls sendError() which should produce a client-side error, not a timeout

Ruled out

  • Ingress proxy timeout — user's nginx ingress has proxy-read-timeout: 3600
  • Missing --hot-reload — confirmed enabled
  • Auth/token issues — other --server commands work with the same credentials
  • Schema validationserve.reload and model.edit are both in the ServerRequestSchema discriminated union
  • Worker protocol intercepting messagesRpcChannel.handleRaw returns false for non-rpc.* message types
  • Local reproduction — operations complete in <1ms locally, even through an nginx reverse proxy with 1s timeout, so could not trigger the timeout

Remaining hypotheses

  1. PVC I/O stalls — if the repo PVC is NFS/EFS-backed, write operations or SQLite file locking (used by serve reload for the extension catalog at .swamp/_extension_catalog.db) could hang indefinitely. model edit writes YAML to the PVC; serve reload opens a SQLite DB on the PVC.

  2. OAuth-specific WebSocket auth latencyauthenticateServerToken runs the server-token model's redeem method on every WebSocket connection, which reads data from the PVC. If PVC I/O is slow, auth could take long enough for something else to timeout.

  3. sendError with id: "unknown" — if validateServerRequest fails (line 1297-1299 of connection.ts), sendError is called with id: "unknown" rather than the request's actual ID. The client filters by message.id !== requestId, so this error frame would be silently ignored and the client would timeout. This is a confirmed bug in the error-reporting path, though it shouldn't trigger for well-formed serve.reload / model.edit messages.

Diagnostic steps for the user

  1. Port-forward test — bypass ingress entirely:

    kubectl port-forward <pod> 4111:4111
    swamp model edit <name> --server ws://127.0.0.1:4111 < definition.yaml
  2. In-pod test — bypass WebSocket/RPC entirely:

    kubectl exec -it <pod> -- swamp model edit <name> < definition.yaml
  3. PVC I/O test — check for stale/slow mounts:

    kubectl exec -it <pod> -- time dd if=/dev/zero of=/repo/testfile bs=1k count=1
    kubectl exec -it <pod> -- rm /repo/testfile
  4. Debug logging — start serve with --log-level debug and retry the failing command; check for WebSocket auth entries and message dispatch logs.

  • PR #2091 fixes a related EXDEV (cross-device rename) crash in the same Kubernetes environment during migrateGrantDefinitions at serve startup
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/7/2026, 2:07:54 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.