-
Notifications
You must be signed in to change notification settings - Fork 198
Auth middleware returns plain text 401 instead of RFC 6750 compliant JSON error response #4055
Copy link
Copy link
Closed
Labels
Description
Description
When a request arrives at the vMCP (or MCPServer) without an Authorization header, the auth middleware returns a 401 response with a plain text body:
authorization header required
RFC 6750 Section 3 requires the error response body to be JSON:
{
"error": "invalid_token",
"error_description": "authorization header required"
}The Content-Type header is also incorrectly set to text/plain; charset=utf-8 instead of application/json.
Impact
Any RFC 6750-compliant OAuth client that tries to parse the 401 response body as JSON will fail. This is observed with Claude Code, which surfaces the following error:
Error: HTTP 401: Invalid OAuth error response: SyntaxError: JSON Parse error: Unexpected identifier "authorization". Raw body: authorization header required
Root Cause
In pkg/auth/token.go, the Middleware function calls http.Error(w, err.Error(), http.StatusUnauthorized) when the Authorization header is missing. http.Error sets Content-Type: text/plain and writes the raw error string as the body.
tokenString, err := ExtractBearerToken(r)
if err != nil {
w.Header().Set("WWW-Authenticate", v.buildWWWAuthenticate(false, ""))
http.Error(w, err.Error(), http.StatusUnauthorized) // plain text, not JSON
return
}Expected Behaviour
The 401 response should:
- Set
Content-Type: application/json - Return a JSON body conforming to RFC 6750 Section 3
Steps to Reproduce
- Configure a VirtualMCPServer with
incomingAuth.type: oidc - Connect with an MCP client (e.g. Claude Code) without a valid Bearer token
- Observe the
401response with plain text body
References
- RFC 6750 Section 3 — The WWW-Authenticate Response Header Field
- Relevant code:
pkg/auth/token.go—TokenValidator.Middleware
Reactions are currently unavailable