clockworklabs/SpacetimeDB · error · DatastoreError
Failed to get JWT payload for connection id ({connection_id}
Error message
Failed to get JWT payload for connection id ({connection_id}): {e} What it means
get_jwt_payload scans st_connection_credentials by connection_id and BSATN-decodes each matching row to extract jwt_payload. This error fires only when that read/decode step fails — a missing row returns Ok(None) instead — i.e. the stored credential row's bytes do not match the expected st_connection_credentials row shape (system-table schema drift or corrupted storage).
Source
Thrown at crates/datastore/src/locking_tx_datastore/state_view.rs:329
}
fn get_jwt_payload(&self, connection_id: ConnectionId) -> Result<Option<String>> {
log::trace!("Getting JWT payload for connection id: {}", connection_id.to_hex());
let mut buf: Vec<u8> = Vec::new();
self.iter_by_col_eq(
ST_CONNECTION_CREDENTIALS_ID,
StConnectionCredentialsFields::ConnectionId,
&ConnectionIdViaU128::from(connection_id).into(),
)?
.next()
.map(|row| row.read_via_bsatn::<StConnectionCredentialsRow>(&mut buf).map(|r| r.jwt_payload))
.transpose()
.map_err(|e| {
log::error!(
"[{connection_id}]: get_jwt_payload: failed to get JWT payload for connection id ({connection_id}), error: {e}"
);
DatastoreError::Other(
anyhow!(
"Failed to get JWT payload for connection id ({connection_id}): {e}"
)
)
})
}
}
/// Returns an iterator over all `st_column` rows for `table_id`.
pub(crate) fn iter_st_column_for_table<'a>(
this: &'a (impl StateView + ?Sized),
table_id: &'a AlgebraicValue,
) -> Result<impl 'a + Iterator<Item = RowRef<'a>>> {
this.iter_by_col_eq(ST_COLUMN_ID, StColumnFields::TableId, table_id)
}
pub struct IterMutTx<'a> {
tx_state_ins: Option<(&'a Table, &'a HashMapBlobStore)>,
stage: ScanStage<'a>,View on GitHub (pinned to 6dee26c6ef)
Solutions
- Run the upgrade/migration path for the new version before serving connections
- Re-authenticate connections so stale credential rows are rewritten in the current format
- Verify the code path against a fresh database, then diff behavior against the upgraded one
- Report the decode failure with the versions involved
Defensive patterns
Strategy: try-catch
Try / catch
Wrap get_jwt_payload calls; on this error log the connection_id (as the datastore already does), fail authentication for that connection with a server-error (not a rejected-credential) status, and alert operators — the credential store needs migration or repair. Ok(None) is the normal no-credentials path and must not be conflated with this error.
Prevention
- Run the official upgrade/migration tooling before serving traffic on a new version
- Re-authenticate clients after major upgrades so credential rows are rewritten in the current format
- Alert on any st_* row decode failure — it signals schema drift, not a bad token
When it happens
Trigger: Authentication code calling get_jwt_payload on a database whose st_connection_credentials rows were serialized by an incompatible spacetimedb version; corrupted pages holding the row; a system-table schema change shipped without a data migration.
Common situations: Upgrading spacetimedb across versions that changed system-table layouts while keeping the data directory; long-lived databases reopened after major upgrades; mixed-version replicas.
Related errors
- Unexpected type for 'aud' claim in JWT
- cannot serialize refs without a typespace
- Invalid JSON: failed to parse string
- Tag {tag} is out of range of enum {typeof(T).Name}
- Error getting jwt: {errno}
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/e5ec92dccdb55869.
Report an issue: GitHub.