{"record":{"id":"cf0e6c83f73c1a3f","repo":"clockworklabs/SpacetimeDB","slug":"error-fetching-public-key-for-issuer-raw-issuer","errorCode":null,"errorMessage":"Error fetching public key for issuer {raw_issuer}","messagePattern":"Error fetching public key for issuer (.+?)","errorType":"validation","errorClass":"TokenValidationError","httpStatus":null,"severity":"error","filePath":"crates/core/src/auth/token_validation.rs","lineNumber":260,"sourceCode":"        let keys = key_or_error?;\n        let validator = JwksValidator {\n            issuer: raw_issuer.into(),\n            keyset: keys,\n        };\n        Ok(Arc::new(validator))\n    }\n}\n\n#[async_trait]\nimpl TokenValidator for CachingOidcTokenValidator {\n    async fn validate_token(&self, token: &str) -> Result<SpacetimeIdentityClaims, TokenValidationError> {\n        let raw_issuer = get_raw_issuer(token)?;\n        log::debug!(\"Getting validator for issuer {}\", raw_issuer.clone());\n        let validator = self\n            .cache\n            .get(String::from(raw_issuer.clone()).into())\n            .await\n            .ok_or_else(|| anyhow::anyhow!(\"Error fetching public key for issuer {raw_issuer}\"))?;\n        validator.validate_token(token).await\n    }\n}\n\n// This is a token validator that uses OIDC to validate tokens.\n// This will look up the public key for the issuer and validate against that key.\n// This currently has no caching.\npub struct OidcTokenValidator;\n\n// Get the issuer out of a token without validating the signature.\nfn get_raw_issuer(token: &str) -> Result<Box<str>, TokenValidationError> {\n    // We need the issuer before we know which key to use.\n    // This intentionally does not validate the token.\n    // Callers must only use it for key discovery and must verify the token afterwards.\n    let data = jsonwebtoken::dangerous::insecure_decode::<IncomingClaims>(token)?;\n    Ok(data.claims.issuer)\n}\n","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/3653d2ed498fddbd83b7062aa6bf8970e18635ec/crates/core/src/auth/token_validation.rs#L242-L278","documentation":"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.","triggerScenarios":"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.","commonSituations":"Self-hosted servers without outbound internet validating tokens from public OIDC providers; corporate proxies; typos in issuer configuration; transient provider outages.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# bash: preflight the issuer's discovery/JWKS endpoints from the server host\ncurl -fsS \"${ISSUER}/.well-known/openid-configuration\" | grep -o '\"jwks_uri\":\"[^\"]*\"'\ncurl -fsS \"$(...jwks_uri...)\" >/dev/null && echo reachable","typeGuard":null,"tryCatchPattern":"// Wrap validation with bounded retry for transient key-fetch failures\nfor attempt in 0..3 {\n    match validator.validate_token(token).await {\n        Ok(claims) => return Ok(claims),\n        Err(e) if is_transient_fetch(&e) && attempt < 2 => backoff(attempt).await,\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["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"],"tags":["auth","oidc","jwks","network","server"],"backgroundTag":"jwks-fetch-failed","analyzedSha":"3653d2ed498fddbd83b7062aa6bf8970e18635ec","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}