clockworklabs / clockworklabs/SpacetimeDB

Websocket message exceeding 32 MiB: server logs size error, then connection abort without close handshake

Open
#4,968 1 comment 0 reactions 1 assignee View on GitHub

@joshua-spacetime is already working on this.

Since May 6, 2026.

Dominant language
Rust
Stars
25.2k
Forks
1.1k
Avg merge
2d 7h
Merged PRs (30d)
46

Description

Environment

  • SpacetimeDB version: v2.2.0
  • Image: docker.io/clockworklabs/spacetime:v2.2.0
  • Image digest: sha256:bc85c24909f92983a7912c83e9e32d0dc3726f535886f76be87ce9222d698c3f
  • Deployment: Kubernetes StatefulSet, single replica, --listen-addr=0.0.0.0:3000
  • Client: Rust SDK (spacetimedb_sdk) connecting via websocket

Observed Behavior

A Rust SDK client sends a websocket message of 70,666,292 bytes (67.4 MiB) to a SpacetimeDB
v2.2.0 server. The server rejects the message due to a size limit and aborts the websocket
connection. The client receives a ResetWithoutClosingHandshake error.

Server Logs

Timestamps are UTC, captured via kubectl logs spacetimedb-0 -n ccc. One complete
connect/reject/abort cycle around the requested observation time of 17:02:30Z:

2026-05-06T17:02:29.914527Z DEBUG crates/client-api/src/routes/subscribe.rs:241:
  websocket: New client connected from unknown ip
  with Identity c2001aeb16590eed773b52c68da872638bfc661b5849a64394836e1d603c4a9c
  and ConnectionId 942b14ad35ed27d9b415c02d8ebdcd89

2026-05-06T17:02:29.914946Z DEBUG crates/client-api/src/routes/subscribe.rs:266:
  websocket: Database accepted connection [...]; spawning ws_client_actor and ClientConnection

2026-05-06T17:02:30.271716Z  WARN crates/client-api/src/routes/subscribe.rs:893:
  Websocket receive error: Space limit exceeded: Message too long: 70666292 > 33554432

2026-05-06T17:02:30.271851Z  INFO crates/client-api/src/routes/subscribe.rs:507:
  Client connection ended: ClientActorId(c2001aeb...@942b14ad.../106)

2026-05-06T17:02:30.272115Z  WARN crates/core/src/client/client_connection.rs:734:
  websocket connection aborted for client identity `c2001aeb...603c4a9c`
  and database identity `c2001f39...29cb7830`

The same cycle repeated 118 times within the observation window (first occurrence at
2026-05-06T17:00:13.619041Z, last at 2026-05-06T17:07:52.815523Z), with the same client
identity reconnecting after each abort. The message size was 70666292 and the limit was
33554432 in every occurrence.

Server-Side Limit

The 33,554,432-byte (32 MiB) limit is set at
crates/client-api/src/routes/subscribe.rs lines 218-221 (v2.2.0 tag):

let ws_config = WebSocketConfig::default()
    .max_message_size(Some(0x2000000))
    .max_frame_size(None)
    .accept_unmasked_frames(false);

The WebSocketOptions struct in the same file
(lines 357-392)
defines the fields exposed via config.toml: ping_interval, idle_timeout,
close_handshake_timeout, and incoming_queue_length. max_message_size and max_frame_size
are not fields of that struct.

v2.2.0 Websocket Transport Change

The v2.2.0 release notes
state:

We've introduced a new v3 WebSocket transport that batches multiple logical client messages
into a single frame, cutting per-message overhead while keeping the existing message model
intact (#4761).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.