zeroclaw-labs/zeroclaw · error
Nevis token_validation is 'local' but no jwks_url is configu
Error message
Nevis token_validation is 'local' but no jwks_url is configured. Either set jwks_url or use token_validation = 'remote'.
What it means
NevisAuthProvider::new was configured with token_validation = 'local' but no jwks_url. Local validation means verifying JWT signatures against the provider's published keys, which requires the JWKS endpoint URL; without it the provider cannot validate anything, so construction fails fast instead of silently accepting or rejecting tokens.
Source
Thrown at crates/zeroclaw-runtime/src/security/nevis.rs:109
};
impl NevisAuthProvider {
/// Create a new Nevis auth model_provider from config values.
/// `client_secret` should already be decrypted by the config loader.
pub fn new(
instance_url: String,
realm: String,
client_id: String,
client_secret: Option<String>,
token_validation: &str,
jwks_url: Option<String>,
require_mfa: bool,
session_timeout_secs: u64,
) -> Result<Self> {
let validation_mode = TokenValidationMode::from_str_config(token_validation)?;
if validation_mode == TokenValidationMode::Local && jwks_url.is_none() {
bail!(
"Nevis token_validation is 'local' but no jwks_url is configured. \
Either set jwks_url or use token_validation = 'remote'."
);
}
let http_client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()
.context("Failed to create HTTP client for Nevis")?;
Ok(Self {
instance_url,
realm,
client_id,
client_secret,
validation_mode,
jwks_url,
require_mfa,View on GitHub (pinned to 88bb9c8533)
Solutions
- Set jwks_url, typically https://<nevis-host>/auth/realms/<realm>/protocol/openid-connect/certs.
- Or switch to token_validation = 'remote' to validate via the introspection endpoint (no JWKS needed).
- Add a config schema/lint that requires jwks_url whenever token_validation is local.
- Verify the URL responds: curl <jwks_url> should return a JSON key set.
Example fix
# before token_validation = "local" # (no jwks_url) # after token_validation = "local" jwks_url = "https://nevis.example.com/auth/realms/main/protocol/openid-connect/certs"
Defensive patterns
Strategy: validation
Validate before calling
let mode = token_validation.trim().to_ascii_lowercase();
if mode == "local" && jwks_url.as_deref().map(str::trim).unwrap_or("").is_empty() {
anyhow::bail!("token_validation='local' requires a non-empty jwks_url");
} Try / catch
Err(e) if e.to_string().contains("no jwks_url is configured") => {
// either populate jwks_url or switch token_validation to 'remote'; block startup until fixed
} Prevention
- Add a config lint: jwks_url is required iff token_validation == 'local'.
- Smoke-test the JWKS endpoint (curl) in deployment checks so the URL is verified reachable.
- Keep example configs paired: local mode always shown together with a jwks_url line.
When it happens
Trigger: Enabling local validation without providing jwks_url; jwks_url dropped during config refactor (renamed key, misspelled, commented out); migrating from remote to local validation and forgetting the new required field.
Common situations: Copying a minimal auth config from examples that omit JWKS; key name mismatches like jwksUrl vs jwks_url in templated config; switching modes to reduce introspection load without adding the endpoint.
Related errors
- Local JWKS token validation is not yet implemented. Set toke
- invalid token_validation mode '{other}': expected 'local' or
- oauth2 configured for '{}' but no auth service provided
- gateway registration failed ({status}): {err}
- matrix: {reason} Cannot auto-recover because channels.matrix
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ec49581686e3e249.
Report an issue: GitHub.