{"record":{"id":"791795c836700a6b","repo":"clockworklabs/SpacetimeDB","slug":"invalid-oidc-url-scheme-url","errorCode":null,"errorMessage":"Invalid OIDC URL scheme: {url}","messagePattern":"Invalid OIDC URL scheme: (.+?)","errorType":"error_code","errorClass":"TokenValidationError","httpStatus":null,"severity":"error","filePath":"crates/core/src/auth/token_validation.rs","lineNumber":424,"sourceCode":"        Ok(Self { keys })\n    }\n}\n\nimpl JsonWebKeySet {\n    fn key_with_id(&self, kid: &str) -> Option<&JsonWebKey> {\n        self.keys.iter().find(|key| key.kid.as_deref() == Some(kid))\n    }\n\n    fn keys_without_ids(&self) -> impl Iterator<Item = &JsonWebKey> {\n        self.keys.iter().filter(|key| key.kid.is_none())\n    }\n}\n\nfn validate_url_scheme(url: &str) -> Result<(), TokenValidationError> {\n    if url.starts_with(\"http://\") || url.starts_with(\"https://\") {\n        Ok(())\n    } else {\n        Err(TokenValidationError::Other(anyhow::anyhow!(\n            \"Invalid OIDC URL scheme: {url}\"\n        )))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::time::Duration;\n\n    use crate::auth::identity::{IncomingClaims, SpacetimeIdentityClaims};\n    use crate::auth::token_validation::{\n        BasicTokenValidator, CachingOidcTokenValidator, FullTokenValidator, JwtErrorKind, OidcTokenValidator,\n        TokenSigner, TokenValidationError, TokenValidator,\n    };\n    use crate::auth::JwtKeys;\n    use base64::Engine;\n    use openssl::ec::{EcGroup, EcKey};\n    use serde_json;","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/3653d2ed498fddbd83b7062aa6bf8970e18635ec/crates/core/src/auth/token_validation.rs#L406-L442","documentation":"When building a token validator from an OIDC issuer URL, SpacetimeDB's core validates that the URL scheme is http:// or https:// via validate_url_scheme. Any other scheme (or a missing scheme) is rejected with this TokenValidationError, because OIDC discovery and JWKS fetching require standard HTTP(S) transport.","triggerScenarios":"Calling TokenValidationConfig::from_oidc_url (or related setup) with a URL like \"grpc://...\", \"localhost:8080\" (no scheme), \"ftp://...\", or a URL with leading whitespace so the http(s) prefix check fails.","commonSituations":"Typing the issuer as a bare host without scheme; copying an internal scheme (e.g. grpc://, unix://) into the OIDC URL field; whitespace or invisible characters before the scheme in environment/config values.","solutions":["Prefix the URL with https:// (or http:// only for non-production/local testing)","Trim whitespace and strip hidden characters from the configured URL","Check the config/env value feeding from_oidc_url points at the actual OIDC issuer endpoint","Validate the URL with a parser before passing it into the token validation config"],"exampleFix":"// before\nlet cfg = TokenValidationConfig::from_oidc_url(\"issuer.example.com\")?; // Err: Invalid OIDC URL scheme\n// after\nlet cfg = TokenValidationConfig::from_oidc_url(\"https://issuer.example.com\")?;","handlingStrategy":"validation","validationCode":"fn ensure_https(url: &str) -> Result<&str, String> {\n    let trimmed = url.trim();\n    if trimmed.starts_with(\"https://\") || trimmed.starts_with(\"http://\") {\n        Ok(trimmed)\n    } else {\n        Err(format!(\"OIDC URL must start with https:// or http://, got: {url}\"))\n    }\n}","typeGuard":"fn is_http_url(url: &str) -> bool {\n    url.trim_start().starts_with(\"http://\") || url.trim_start().starts_with(\"https://\")\n}","tryCatchPattern":"let cfg = TokenValidationConfig::from_oidc_url(&url).map_err(|e| {\n    eprintln!(\"OIDC URL validation failed: {e}\");\n    ConfigError::InvalidOidcUrl(url.clone())\n})?;","preventionTips":["Always include the scheme in issuer URLs; prefer https:// everywhere","Trim environment/config values before use to remove stray whitespace","Validate configured URLs at startup with a URL parser, before wiring token validation","Never use non-HTTP schemes (grpc://, unix://) for the OIDC issuer field"],"tags":["rust","spacetimedb","oidc","url","auth"],"backgroundTag":"invalid-url","analyzedSha":"3653d2ed498fddbd83b7062aa6bf8970e18635ec","analyzedAt":"2026-09-06T02:33:02.036Z","contentChangedAt":"2026-09-06T02:33:02.036Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}