Misleading auth log: static_token_mismatch reported for token_type: "jwt" when the JWT validator is unavailable #58

Open
opened 2026-07-17 13:02:46 +00:00 by mathias · 0 comments
Owner

Problem

When the JWT validator failed to initialize, every rejected JWT logged this:

WARN mcp auth rejected reason="static_token_mismatch" status=401 token_type="jwt" token_fp="872d2da957ac" path="/mcp"

The reason is technically accurate — the code did fall through to a static-token comparison and it did mismatch — but it is actively misleading. static_token_mismatch reads as "the caller presented the wrong token". The truth was "the server's JWT validator is dead, so a correct token had no chance of validating". The fields even contradict each other: token_type: "jwt" next to a static token failure is the tell, and it is easy to miss.

This misdirection propagated all the way to the user: claude.ai surfaced Authorization with gitea failed. You can check your credentials and permissions. The credentials were valid. Time went into re-running the Authentik OAuth flow before the server logs were read.

Proposed fix

When a JWT is presented and the validator is unavailable, log a distinct reason:

WARN mcp auth rejected reason="jwt_validator_unavailable" status=401 token_type="jwt" ...

Reserve static_token_mismatch for token_type: "static". Never let a JWT path report a static-token failure.

Consider also returning 503 rather than 401 in this case: the server is degraded, the request is not unauthorized. A 503 would tell an upstream client to retry rather than tell a user to check their credentials.

Acceptance criterion

A test asserting that with a nil/failed validator, a well-formed JWT yields reason jwt_validator_unavailable (not static_token_mismatch).

Refs

  • Companion to the one-shot validator init issue.
  • Observed on v0.11.0, koala k3s, 2026-07-17.
## Problem When the JWT validator failed to initialize, every rejected JWT logged this: ``` WARN mcp auth rejected reason="static_token_mismatch" status=401 token_type="jwt" token_fp="872d2da957ac" path="/mcp" ``` The reason is technically accurate — the code did fall through to a static-token comparison and it did mismatch — but it is actively misleading. `static_token_mismatch` reads as "the caller presented the wrong token". The truth was "the server's JWT validator is dead, so a correct token had no chance of validating". The fields even contradict each other: `token_type: "jwt"` next to a *static* token failure is the tell, and it is easy to miss. This misdirection propagated all the way to the user: claude.ai surfaced `Authorization with gitea failed. You can check your credentials and permissions.` The credentials were valid. Time went into re-running the Authentik OAuth flow before the server logs were read. ## Proposed fix When a JWT is presented and the validator is unavailable, log a distinct reason: ``` WARN mcp auth rejected reason="jwt_validator_unavailable" status=401 token_type="jwt" ... ``` Reserve `static_token_mismatch` for `token_type: "static"`. Never let a JWT path report a static-token failure. Consider also returning 503 rather than 401 in this case: the server is degraded, the request is not unauthorized. A 503 would tell an upstream client to retry rather than tell a user to check their credentials. ## Acceptance criterion A test asserting that with a nil/failed validator, a well-formed JWT yields reason `jwt_validator_unavailable` (not `static_token_mismatch`). ## Refs - Companion to the one-shot validator init issue. - Observed on v0.11.0, koala k3s, 2026-07-17.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/gitea-mcp#58