clockworklabs/SpacetimeDB · error · TokenValidationError
Invalid OIDC URL scheme: {url}
Error message
Invalid OIDC URL scheme: {url} What it means
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.
Source
Thrown at crates/core/src/auth/token_validation.rs:424
Ok(Self { keys })
}
}
impl JsonWebKeySet {
fn key_with_id(&self, kid: &str) -> Option<&JsonWebKey> {
self.keys.iter().find(|key| key.kid.as_deref() == Some(kid))
}
fn keys_without_ids(&self) -> impl Iterator<Item = &JsonWebKey> {
self.keys.iter().filter(|key| key.kid.is_none())
}
}
fn validate_url_scheme(url: &str) -> Result<(), TokenValidationError> {
if url.starts_with("http://") || url.starts_with("https://") {
Ok(())
} else {
Err(TokenValidationError::Other(anyhow::anyhow!(
"Invalid OIDC URL scheme: {url}"
)))
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use crate::auth::identity::{IncomingClaims, SpacetimeIdentityClaims};
use crate::auth::token_validation::{
BasicTokenValidator, CachingOidcTokenValidator, FullTokenValidator, JwtErrorKind, OidcTokenValidator,
TokenSigner, TokenValidationError, TokenValidator,
};
use crate::auth::JwtKeys;
use base64::Engine;
use openssl::ec::{EcGroup, EcKey};
use serde_json;View on GitHub (pinned to 3653d2ed49)
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
Example fix
// before
let cfg = TokenValidationConfig::from_oidc_url("issuer.example.com")?; // Err: Invalid OIDC URL scheme
// after
let cfg = TokenValidationConfig::from_oidc_url("https://issuer.example.com")?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_https(url: &str) -> Result<&str, String> {
let trimmed = url.trim();
if trimmed.starts_with("https://") || trimmed.starts_with("http://") {
Ok(trimmed)
} else {
Err(format!("OIDC URL must start with https:// or http://, got: {url}"))
}
} Type guard
fn is_http_url(url: &str) -> bool {
url.trim_start().starts_with("http://") || url.trim_start().starts_with("https://")
} Try / catch
let cfg = TokenValidationConfig::from_oidc_url(&url).map_err(|e| {
eprintln!("OIDC URL validation failed: {e}");
ConfigError::InvalidOidcUrl(url.clone())
})?; Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- cannot serialize refs without a typespace
- Invalid JSON: failed to parse string
- length didn't fit in `u32`
- `close` was called on this `NoDurability` instance
- Error looking up name for truncated table {table_id:?}
AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-09-06).
Data as JSON: /api/errors/791795c836700a6b.
Report an issue: GitHub.