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
401 response with plain text body
References
Description
When a request arrives at the vMCP (or MCPServer) without an
Authorizationheader, the auth middleware returns a401response with a plain text body:RFC 6750 Section 3 requires the error response body to be JSON:
{ "error": "invalid_token", "error_description": "authorization header required" }The
Content-Typeheader is also incorrectly set totext/plain; charset=utf-8instead ofapplication/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:
Root Cause
In
pkg/auth/token.go, theMiddlewarefunction callshttp.Error(w, err.Error(), http.StatusUnauthorized)when the Authorization header is missing.http.ErrorsetsContent-Type: text/plainand writes the raw error string as the body.Expected Behaviour
The 401 response should:
Content-Type: application/jsonSteps to Reproduce
incomingAuth.type: oidc401response with plain text bodyReferences
pkg/auth/token.go—TokenValidator.Middleware