Skip to content

Terminal stuck at "connecting" — Caddy gzip encoding breaks SSE stream (EventSource drops immediately) #419

@witcher112

Description

@witcher112

Summary

The terminal panel is permanently stuck at "connecting" when using a self-hosted instance behind a Caddy reverse proxy with encode gzip enabled. The root cause is that Caddy's gzip middleware compresses the /api/control/stream SSE response, which causes the browser's EventSource API to drop the connection immediately.

Root cause

Caddy's encode gzip directive applies compression to all responses, including text/event-stream responses. This is incompatible with SSE:

  • SSE requires unbuffered, real-time flushing of individual events
  • gzip compression buffers output before sending, breaking the protocol
  • The browser's EventSource implementation receives a Content-Encoding: gzip header on what should be an uncompressed stream and drops the connection within ~1ms

Because the SSE stream never stays connected, the frontend never receives the workspace ready/status events, and the terminal WebSocket connection is never initiated — leaving the UI stuck at "connecting" indefinitely.

Impact

Any deployment using a reverse proxy with gzip compression (Caddy, nginx with gzip on, etc.) without explicit SSE exclusions will silently break the terminal. The rest of the UI (missions, agent output, etc.) continues to work because standard JSON responses are unaffected.

Suggested fix

The default Caddyfile template shipped with sandboxed.sh (or the documentation) should exclude streaming endpoints from compression:

sandboxed-sh-agent.example.com {
    reverse_proxy localhost:3000

    @compressible {
        not path /api/control/stream /api/desktop/stream /api/task/*/stream /api/monitoring/ws/v1
        not header Accept text/event-stream
    }
    encode @compressible gzip

    request_body {
        max_size 50MB
    }
}

Alternatively, the server itself could set Cache-Control: no-transform on SSE responses, which instructs compliant proxies not to modify the response encoding.

Environment

  • sandboxed_sh v0.11.1
  • Caddy v2.x (reverse proxy)
  • Chrome 144 (macOS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions