{"record":{"id":"c4fe58bb2e034adb","repo":"zeroclaw-labs/zeroclaw","slug":"token-is-not-active-revoked-or-expired","errorCode":null,"errorMessage":"Token is not active (revoked or expired)","messagePattern":"Token is not active \\(revoked or expired\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/security/nevis.rs","lineNumber":202,"sourceCode":"            .form(&form)\n            .send()\n            .await\n            .context(\"Failed to reach Nevis introspection endpoint\")?;\n\n        if !resp.status().is_success() {\n            bail!(\n                \"Nevis introspection returned HTTP {}\",\n                resp.status().as_u16()\n            );\n        }\n\n        let body: IntrospectionResponse = resp\n            .json()\n            .await\n            .context(\"Failed to parse Nevis introspection response\")?;\n\n        if !body.active {\n            bail!(\"Token is not active (revoked or expired)\");\n        }\n\n        let user_id = body\n            .sub\n            .filter(|s| !s.trim().is_empty())\n            .context(\"Token has missing or empty `sub` claim\")?;\n\n        let mut roles = body.realm_access.map(|ra| ra.roles).unwrap_or_default();\n        roles.sort();\n        roles.dedup();\n\n        Ok(NevisIdentity {\n            user_id,\n            roles,\n            scopes: body\n                .scope\n                .unwrap_or_default()\n                .split_whitespace()","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/security/nevis.rs#L184-L220","documentation":"The introspection endpoint answered 2xx with active = false (nevis.rs:201-203). Nevis considers the token inactive: revoked, expired, or not issued for this client/realm. This is a definitive negative answer from the IdP, not a network or parse problem.","triggerScenarios":"validate_token with a revoked or expired access token; a token minted by a different realm or for a different client; a user logged out via the admin console so their token was revoked.","commonSituations":"Frontend kept a token in localStorage after logout; access-token lifespan shorter than the app session; staging token sent to the prod Nevis instance.","solutions":["Reject with 401 and have the client re-authenticate, or use its refresh token once and re-validate","If tokens die early, check the access token lifespan configured on the Nevis client","Confirm the token was issued by the same instance_url/realm the provider is configured with"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Match err.to_string().contains(\"Token is not active\") and return 401; invalidate any locally cached token for that caller and at most one refresh attempt before re-validating.","preventionTips":["Drop cached tokens on the first 401 instead of replaying them","Refresh tokens proactively before expected expiry","Use one Nevis realm per environment so cross-environment tokens fail predictably"],"tags":["auth","nevis","oauth","token-revocation","rust"],"backgroundTag":"token-revoked-or-expired","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}