Search engines love error messages, and so will you when you paste KVCH_E_AGENT_TOKEN_EXPIRED into Google at 2am. This page exists so that search lands here, and you leave with a fix rather than a forum thread from 2019.
kavachOS surfaces structured errors everywhere: HTTP responses, SDK exceptions, audit log entries. Every error has a code field, an message field, and a docs_url that points to the relevant section of the errors reference. The families below map to how the system is organized internally. Finding the right family first cuts your debugging time in half.
{
"error": {
"code": "KVCH_E_AGENT_TOKEN_EXPIRED",
"message": "The agent token has expired. Re-issue via agents.refreshToken().",
"docs_url": "https://docs.kavachos.com/errors#KVCH_E_AGENT_TOKEN_EXPIRED",
"request_id": "req_01HZ9XKJVBM3DQNPZ7W4LYRTF",
"timestamp": "2026-04-02T02:14:33.081Z"
}
}01
Agent identity errors (KVCH_E_AGENT_*)
These fire when something goes wrong with an agent credential. They are the most common category in production and nearly always fixable without a support ticket. Full model is documented in agent identity.
| Code | Cause | Fix |
|---|---|---|
| KVCH_E_AGENT_TOKEN_EXPIRED | Agent access token TTL exceeded (default 30 min). | Call agents.refreshToken() before expiry, or reduce token lifetime to match your task duration. |
| KVCH_E_AGENT_NOT_FOUND | Agent ID does not exist in this project. | Verify you are using the correct project API key. Agent IDs are project-scoped. |
| KVCH_E_AGENT_PERMISSION_DENIED | Agent tried to call a scope it was not granted. | Update the agent definition with the required scope, or reduce the operation to the existing scope set. |
| KVCH_E_AGENT_DELEGATION_DEPTH | Delegation chain exceeds the 5-level maximum. | Flatten your agent graph. If you genuinely need depth > 5, contact support for an override. |
| KVCH_E_AGENT_REVOKED | The agent was explicitly revoked by a user or admin. | Check the audit log for the revocation event. Create a new agent if the use case is still valid. |
| KVCH_E_AGENT_SUSPENDED | Automatic suspension triggered by anomaly detection (e.g. 50+ consecutive 403s). | Review the anomaly in the dashboard, clear the flag via agents.unsuspend(), then address the root permission issue. |
import { KavachError } from 'kavachos';
try {
const result = await kavach.agents.call(agentId, payload);
} catch (err) {
if (err instanceof KavachError && err.code === 'KVCH_E_AGENT_TOKEN_EXPIRED') {
await kavach.agents.refreshToken(agentId);
// retry once
return kavach.agents.call(agentId, payload);
}
throw err;
}02
Session errors (KVCH_E_SESSION_*)
Session errors involve human-facing authentication states. Most are benign: the user closed a tab, refreshed from a different browser, or let a session expire overnight. A few require code changes.
| Code | Cause | Fix |
|---|---|---|
| KVCH_E_SESSION_EXPIRED | Session lifetime elapsed. Default is 7 days for web, 30 days for mobile. | Redirect to sign-in. Extend lifetime via project settings if your users complain about frequency. |
| KVCH_E_SESSION_INVALID | Session token is malformed, tampered, or signed with a rotated key. | Force sign-out and re-authentication. If this fires in bulk, check if you recently rotated signing keys without a migration window. |
| KVCH_E_SESSION_NOT_FOUND | Session ID does not exist in D1. May have been deleted manually. | Treat as expired. Redirect to sign-in. |
| KVCH_E_SESSION_DEVICE_MISMATCH | Device fingerprint changed mid-session. Common after browser updates or VPN switches. | Re-authenticate the user. If this triggers too often for legitimate users, relax device-binding in project settings. |
| KVCH_E_SESSION_CONCURRENT_LIMIT | User has reached the max concurrent sessions set for the project (default: 5). | Prompt the user to end an existing session, or raise the limit in project settings. |
| KVCH_E_SESSION_MFA_REQUIRED | Project policy requires MFA but the session was created before MFA was enrolled. | Redirect to /mfa/setup. The SDK method auth.requireMfaStep() handles the redirect automatically. |
03
OAuth errors (KVCH_E_OAUTH_*)
OAuth errors surface during the authorization code flow, token exchange, or refresh cycle. The most common culprit is a misconfigured redirect URI. If you are connecting external providers, the configuration guide covers setup steps.
| Code | Cause | Fix |
|---|---|---|
| KVCH_E_OAUTH_REDIRECT_MISMATCH | The redirect_uri in the request does not match any registered URI for the client. | Add the exact URI (including trailing slash if used) to your provider settings in the dashboard. |
| KVCH_E_OAUTH_STATE_INVALID | The state parameter returned by the provider does not match what was sent. | Ensure you are storing and reading state from the same session store. CSRF attacks can also cause this. |
| KVCH_E_OAUTH_CODE_EXPIRED | Authorization codes expire after 60 seconds. The exchange happened too late. | Reduce latency between authorization and token exchange. If behind a slow CDN, check edge caching is not buffering the callback. |
| KVCH_E_OAUTH_TOKEN_REVOKED | The provider revoked the OAuth token (user disconnected your app from their provider account). | Catch this error in your OAuth refresh logic and prompt re-authorization. |
| KVCH_E_OAUTH_PROVIDER_UNAVAILABLE | Provider returned a 5xx or timed out during the token exchange. | Retry with exponential backoff. Consider showing the user an alternative sign-in method. |
| KVCH_E_OAUTH_SCOPE_INSUFFICIENT | The token does not have the scope your app requested. | Re-initiate the OAuth flow with the required scopes. Users may have unchecked a permission during the consent screen. |
04
MCP errors (KVCH_E_MCP_*)
MCP errors come from the OAuth 2.1 layer that kavachOS exposes for Model Context Protocol clients. If you are wiring up a tool server or an MCP client for the first time, read the MCP OAuth guide before debugging here. Most MCP errors have a structural cause that becomes obvious once you see the wire format.
| Code | Cause | Fix |
|---|---|---|
| KVCH_E_MCP_CLIENT_UNREGISTERED | The MCP client ID was not registered via dynamic client registration (RFC 7591). | POST to /.well-known/oauth/register with your client metadata before initiating the flow. |
| KVCH_E_MCP_PKCE_MISSING | OAuth 2.1 requires PKCE for all public clients. code_challenge was absent. | Generate a code_verifier, hash it with S256, and send code_challenge + code_challenge_method in the auth request. |
| KVCH_E_MCP_PKCE_VERIFY_FAILED | code_verifier does not match the stored code_challenge. | Ensure you are using the same verifier string from the authorization step. Do not regenerate it. |
| KVCH_E_MCP_RESOURCE_INDICATOR_INVALID | The resource parameter (RFC 8707) points to a server not registered in this project. | Add the MCP server URI in your project dashboard under MCP Servers, then retry. |
| KVCH_E_MCP_METADATA_FETCH_FAILED | kavachOS could not retrieve the authorization server metadata (RFC 8414) from the URL you specified. | Confirm that /.well-known/oauth-authorization-server is reachable and returns valid JSON. |
| KVCH_E_MCP_TOOL_AUTH_REQUIRED | The tool requires a delegated token but the calling agent did not present one. | Use kavachos.agents.delegate() to get a scoped token before calling the tool. |
// One-time registration before your first OAuth flow
const registration = await fetch(
'https://auth.kavachos.com/.well-known/oauth/register',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_name: 'my-mcp-tool-server',
redirect_uris: ['https://my-server.com/callback'],
token_endpoint_auth_method: 'none', // public client
grant_types: ['authorization_code'],
response_types: ['code'],
}),
}
);
const { client_id } = await registration.json();
// Store client_id; use it in every subsequent auth request05
Rate limit errors (KVCH_E_RATE_*)
Rate limits in kavachOS operate at four levels: global project, per-agent, per-user, and per-endpoint. When you hit a limit, the response includes a Retry-After header in seconds. The full policy is documented in the rate limits section of the API reference.
| Code | Cause | Fix |
|---|---|---|
| KVCH_E_RATE_PROJECT_EXCEEDED | Your project hit its plan-level request limit (requests per minute across all endpoints). | Upgrade your plan, or add exponential backoff. Check the dashboard for which endpoint is generating volume. |
| KVCH_E_RATE_AGENT_EXCEEDED | A single agent identity exceeded its per-minute request budget. | Spread load across multiple agent identities, or request a higher per-agent limit in project settings. |
| KVCH_E_RATE_USER_EXCEEDED | A single user account triggered too many auth attempts (default: 10 per minute). | This is intentional brute-force protection. If legitimate users hit it, increase the threshold in project settings. |
| KVCH_E_RATE_SIGNUP_EXCEEDED | New account creation rate exceeded (default: 50 signups per hour per project). | If you are running a migration or bulk import, use the bulk import API instead of the signup endpoint. |
| KVCH_E_RATE_OTP_EXCEEDED | OTP or magic link requests exceeded the limit of 5 per 10 minutes per user. | Show a message telling the user to wait. If they are testing, increase the limit in dev mode via environment flags. |
async function callWithRetry(fn: () => Promise<unknown>, maxAttempts = 3) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
if (
err instanceof KavachError &&
err.code.startsWith('KVCH_E_RATE_') &&
attempt < maxAttempts
) {
const retryAfter = err.retryAfter ?? 5;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
continue;
}
throw err;
}
}
}06
When to file a bug vs fix in code
Every code in this reference has a known cause. If you are seeing one and the fix column does not resolve it, there are two likely explanations: either the error is masking a different root cause (check request_id in the response for the full trace), or you have found a genuine bug.
File a bug when: the error code does not match what you sent, the error fires on a request that was identical to one that succeeded seconds earlier, or the fix in this table produces the same error. The request_id from the error response is the fastest thing to include in a bug report. It lets us pull the full server-side trace within seconds.
Topics
- #kavachOS error codes
- #auth errors
- #auth debugging
- #error reference
- #authentication troubleshooting
Keep going in the docs
Reference
API reference
Every function, option, and return type in the kavachOS SDK.
Agents
Agent identity
Cryptographic bearer tokens, wildcard permissions, and per-agent budgets. The core primitive.
MCP
MCP OAuth 2.1
Full OAuth 2.1 authorization server for MCP, compliant with RFC 9728, 8414, and 7591.
Agents
Audit trails
Tamper-evident logs of every token issue, call, and denial. EU AI Act and SOC 2 ready.
Read next
- Engineering
Agent delegation chains: the pattern everyone gets wrong
Three broken ways to let agents spawn helpers, and one model that keeps audit trails intact.
8 min read - Tutorial
Building an MCP tool server with auth, end to end
Scaffold the server, wire up OAuth, write tools, test with Claude.
15 min read
Share this post
Get started
Try kavachOS Cloud free
Free up to 1,000 MAU. No credit card required.