clockworklabs/SpacetimeDB · error · TokenValidationError
Error fetching public key for issuer
Error message
Error fetching public key for issuer {raw_issuer} What it means
CachingOidcTokenValidator resolves a validator per issuer by fetching the issuer's public keys through an async cache; when the cache lookup returns None the fetch failed, and the ok_or_else collapses the underlying cause into this generic message. The issuer's key endpoint was unreachable or errored.
Solutions
- From the server host, verify reachability: `curl <issuer>/.well-known/openid-configuration` and the jwks_uri it advertises
- Fix DNS/egress/firewall so spacetimedb can reach the issuer over TLS
- Confirm the token's iss claim matches the issuer actually configured on the server
- Retry after transient network issues — key fetches are cached, so cache expiry or a restart re-attempts
Defensive patterns
Strategy: retry
Validate before calling
# bash: preflight the issuer's discovery/JWKS endpoints from the server host
curl -fsS "${ISSUER}/.well-known/openid-configuration" | grep -o '"jwks_uri":"[^"]*"'
curl -fsS "$(...jwks_uri...)" >/dev/null && echo reachable Try / catch
// Wrap validation with bounded retry for transient key-fetch failures
for attempt in 0..3 {
match validator.validate_token(token).await {
Ok(claims) => return Ok(claims),
Err(e) if is_transient_fetch(&e) && attempt < 2 => backoff(attempt).await,
Err(e) => return Err(e),
}
} Prevention
- Monitor egress from spacetimedb hosts to your OIDC providers (DNS, TLS, proxy rules)
- Cache and alert on JWKS reachability so key-fetch failures surface before users hit them
When it happens
Trigger: Authenticating with an OIDC-issued token while the issuer's JWKS endpoint cannot be fetched from the spacetimedb host: wrong/unreachable issuer URL, DNS failure, TLS errors, firewall blocking egress, or an iss claim pointing at a host the server cannot resolve.
Common situations: Self-hosted servers without outbound internet validating tokens from public OIDC providers; corporate proxies; typos in issuer configuration; transient provider outages.
Related errors
AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-08-20).
Data as JSON: /api/errors/cf0e6c83f73c1a3f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/core/src/auth/token_validation.rs:260
let keys = key_or_error?;
let validator = JwksValidator {
issuer: raw_issuer.into(),
keyset: keys,
};
Ok(Arc::new(validator))
}
}
#[async_trait]
impl TokenValidator for CachingOidcTokenValidator {
async fn validate_token(&self, token: &str) -> Result<SpacetimeIdentityClaims, TokenValidationError> {
let raw_issuer = get_raw_issuer(token)?;
log::debug!("Getting validator for issuer {}", raw_issuer.clone());
let validator = self
.cache
.get(String::from(raw_issuer.clone()).into())
.await
.ok_or_else(|| anyhow::anyhow!("Error fetching public key for issuer {raw_issuer}"))?;
validator.validate_token(token).await
}
}
// This is a token validator that uses OIDC to validate tokens.
// This will look up the public key for the issuer and validate against that key.
// This currently has no caching.
pub struct OidcTokenValidator;
// Get the issuer out of a token without validating the signature.
fn get_raw_issuer(token: &str) -> Result<Box<str>, TokenValidationError> {
// We need the issuer before we know which key to use.
// This intentionally does not validate the token.
// Callers must only use it for key discovery and must verify the token afterwards.
let data = jsonwebtoken::dangerous::insecure_decode::<IncomingClaims>(token)?;
Ok(data.claims.issuer)
}
View on GitHub (pinned to 3653d2ed49)