clockworklabs/SpacetimeDB · error · DBError::Other

v2 subscriptions require binary protocol

Error message

v2 subscriptions require binary protocol

What it means

On the v2 subscribe path, the initial evaluation of the subscribed queries must produce BSATN updates so they can be converted into ws_v2::QueryRows for SubscribeApplied. evaluate_queries returned FormatSwitch::Json instead, so the rows cannot be shipped to a v2 client and the subscribe fails with this error.

Source

Thrown at crates/core/src/subscription/module_subscription_actor.rs:1410

            self.remove_failed_subscription(subscription_metrics, sender.id, failed_subscription)?;
            send_err_msg(err.to_string().into());
            return Ok((None, trapped));
        }

        let Ok((update, metrics)) = self.evaluate_queries(sender.clone(), &queries, &tx, TableUpdateType::Subscribe)
        else {
            self.remove_failed_subscription(subscription_metrics, sender.id, failed_subscription)?;
            send_err_msg("Internal error evaluating queries".into());
            return Ok((None, trapped));
        };
        tx.metrics.merge(metrics);

        subscription_metrics.num_queries_evaluated.inc_by(queries.len() as _);

        let ws_v2::QueryRows { tables } = match update {
            ws_v1::FormatSwitch::Bsatn(update) => query_rows_from_update(update, false)?,
            ws_v1::FormatSwitch::Json(_) => {
                return Err(DBError::Other(anyhow::anyhow!(
                    "v2 subscriptions require binary protocol"
                )))
            }
        };

        let _ = self.broadcast_queue.send_client_message_v2(
            sender.clone(),
            Some(tx_offset),
            ws_v2::SubscribeApplied {
                request_id: request.request_id,
                query_set_id: request.query_set_id,
                rows: ws_v2::QueryRows { tables },
            },
        );

        Ok((Some(metrics), trapped))
    }
    fn add_multi_subscription_inner<I: WasmInstance>(

View on GitHub (pinned to 9e0d92412f)

Solutions

  1. Upgrade both client and server to matched versions with v2 binary protocol support
  2. Verify the client connects with the v2 protocol so BSATN is used end-to-end
  3. In custom builds, ensure BSATN (not JSON) is selected for v2 subscription evaluation
Defensive patterns

Strategy: validation

Validate before calling

// Client-side guard: only use v2 subscribe when the connection negotiated binary
if !connection.negotiated_v2_binary() {
    return Err(anyhow::anyhow!("v2 subscribe requires a server and client with matching binary protocol support"));
}

Try / catch

match subscribe_result {
    Err(e) if e.to_string().contains("v2 subscriptions require binary protocol") => {
        // Fall back to the v1 protocol or upgrade the server, then resubscribe
    }
    other => other,
}

Prevention

When it happens

Trigger: A v2 (binary protocol) client subscribing when the subscription actor evaluates queries under the JSON format - format mismatch between the negotiated protocol and evaluation settings.

Common situations: Version skew between client and server; servers without v2 support serving v2 clients; forced format settings in custom builds.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@9e0d92412f (2026-08-20). Data as JSON: /api/errors/0896ffea126a3c19. Report an issue: GitHub.