zeroclaw-labs/zeroclaw · error
invalid token_validation mode '{other}': expected 'local' or
Error message
invalid token_validation mode '{other}': expected 'local' or 'remote' What it means
TokenValidationMode::from_str_config received a string that is neither 'local' nor 'remote' (comparison is case-insensitive but not trim-tolerant). This value decides whether Nevis tokens are validated locally against a JWKS endpoint or remotely via introspection, so an unknown mode fails fast at provider construction.
Source
Thrown at crates/zeroclaw-runtime/src/security/nevis.rs:36
/// When this session expires (seconds since UNIX epoch).
pub session_expiry: u64,
}
/// Token validation strategy.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenValidationMode {
/// Validate JWT locally using cached JWKS keys.
Local,
/// Validate token by calling the Nevis introspection endpoint.
Remote,
}
impl TokenValidationMode {
pub fn from_str_config(s: &str) -> Result<Self> {
match s.to_ascii_lowercase().as_str() {
"local" => Ok(Self::Local),
"remote" => Ok(Self::Remote),
other => bail!("invalid token_validation mode '{other}': expected 'local' or 'remote'"),
}
}
}
/// Authentication model_provider backed by a Nevis instance.
/// Validates tokens, manages sessions, and resolves identities. The model_provider
/// is designed to be shared across concurrent requests (`Send + Sync`).
pub struct NevisAuthProvider {
/// Base URL of the Nevis instance (e.g. `https://nevis.example.com`).
instance_url: String,
/// Nevis realm to authenticate against.
realm: String,
/// OAuth2 client ID registered in Nevis.
client_id: String,
/// OAuth2 client secret (decrypted at startup).
client_secret: Option<String>,
/// Token validation strategy.
validation_mode: TokenValidationMode,View on GitHub (pinned to 88bb9c8533)
Solutions
- Set the value to exactly 'local' or 'remote' (any case, no surrounding whitespace).
- If remote introspection is wanted, use 'remote'; for local JWKS validation use 'local' and also set jwks_url.
- Validate the value at config load with a lint/schema check before the provider is constructed.
- Watch for whitespace: trim env-sourced values before passing them in.
Example fix
# before token_validation = "introspection" # after token_validation = "remote" # or "local" with a jwks_url set
Defensive patterns
Strategy: validation
Validate before calling
let mode = token_validation.trim().to_ascii_lowercase();
if !matches!(mode.as_str(), "local" | "remote") {
anyhow::bail!("token_validation must be 'local' or 'remote', got '{token_validation}'");
} Type guard
fn is_valid_token_validation_mode(s: &str) -> bool {
matches!(s.trim().to_ascii_lowercase().as_str(), "local" | "remote")
} Try / catch
Err(e) if e.to_string().starts_with("invalid token_validation mode") => {
// surface to the operator with the allowed values; fail deployment, don't guess a default
} Prevention
- Use a config schema/enum parser so invalid modes fail at load with a clear message.
- Trim and lowercase env-sourced values before passing them to the provider.
- Keep an allow-list test for accepted mode spellings when config formats change.
When it happens
Trigger: Setting token_validation = "introspection", "jwt", "JWKS", "remot" (typo), or " local" with a leading space; values passed from env vars or templated config without normalization.
Common situations: Config copied from another auth system with different mode names; YAML values quoted with stray whitespace; version migrations renaming the option; uppercase values work ('Local') but padded ones do not.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- security.nevis: {msg}
- Nevis token_validation is 'local' but no jwks_url is configu
- Local JWKS token validation is not yet implemented. Set toke
- 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/0427b8ea5c85f988.
Report an issue: GitHub.