zeroclaw-labs/zeroclaw · error
Nevis introspection returned HTTP {}
Error message
Nevis introspection returned HTTP {} What it means
In remote mode the provider POSTs to {instance_url}/auth/realms/{realm}/protocol/openid-connect/token/introspect (nevis.rs:167-194). The endpoint answered with a non-2xx status. Typical causes: 401 wrong client_id/client_secret, 404 wrong realm or instance_url path, 5xx IdP or reverse-proxy outage.
Source
Thrown at crates/zeroclaw-runtime/src/security/nevis.rs:190
let mut form = vec![("token", token), ("client_id", &self.client_id)];
// client_secret is optional (public clients don't need it)
let secret_ref;
if let Some(ref secret) = self.client_secret {
secret_ref = secret.as_str();
form.push(("client_secret", secret_ref));
}
let resp = self
.http_client
.post(&introspect_url)
.form(&form)
.send()
.await
.context("Failed to reach Nevis introspection endpoint")?;
if !resp.status().is_success() {
bail!(
"Nevis introspection returned HTTP {}",
resp.status().as_u16()
);
}
let body: IntrospectionResponse = resp
.json()
.await
.context("Failed to parse Nevis introspection response")?;
if !body.active {
bail!("Token is not active (revoked or expired)");
}
let user_id = body
.sub
.filter(|s| !s.trim().is_empty())
.context("Token has missing or empty `sub` claim")?;View on GitHub (pinned to 88bb9c8533)
Solutions
- Verify client_id and client_secret match a client registered in the same Nevis realm (HTTP 401 is the tell)
- Check instance_url and realm — provider.instance_url() and provider.realm() expose what was configured; 404 usually means one is wrong
- Run provider.health_check() to confirm the realm root is reachable at all
- For 5xx statuses, retry with backoff and a circuit breaker instead of failing every request
Defensive patterns
Strategy: try-catch
Validate before calling
if let Err(e) = provider.health_check().await {
tracing::warn!(error = %e, "nevis unreachable at startup; token validation may fail");
} Try / catch
Parse the trailing HTTP code from the message: 401/403 -> fail fast with a config-error alert (credentials); 404 -> alert on realm/URL mismatch; 5xx -> retry with exponential backoff behind a circuit breaker and emit 503 to callers.
Prevention
- Run provider.health_check() at startup so credential and realm mistakes surface at boot, not first request
- Keep a runbook mapping introspection 401/404/5xx to config vs outage causes
- Alert on repeated introspection 5xx as an IdP outage, not as per-user auth failures
When it happens
Trigger: validate_token with TokenValidationMode::Remote when the Nevis client credentials are wrong, the realm name is misspelled, instance_url has a wrong prefix, or the IdP/proxy returns 502/503.
Common situations: Client secret rotated on the IdP but not in ZeroClaw config; staging instance_url pasted into prod config; realm 'master' used instead of the actual realm; firewall or mTLS rules blocking the introspection path.
Related errors
- Nevis session validation returned HTTP {}
- Token is not active (revoked or expired)
- Nevis health check failed: HTTP {}
- GET /users/me/channels returned {}
- login failed ({status}): {body}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/d94bbf646c023b2b.
Report an issue: GitHub.