{"record":{"id":"0623b4416f04d39f","repo":"github/github-mcp-server","slug":"bad-request-unsupported-authorization-header","errorCode":null,"errorMessage":"bad request: unsupported Authorization header","messagePattern":"bad request: unsupported Authorization header","errorType":"http","errorClass":"utils.ErrUnsupportedAuthorizationHeader","httpStatus":400,"severity":"error","filePath":"pkg/http/middleware/token.go","lineNumber":34,"sourceCode":"\t\t\tctx := r.Context()\n\n\t\t\t// Check if token info already exists in context, if it does, skip extraction.\n\t\t\t// In remote setup, we may have already extracted token info earlier.\n\t\t\tif _, ok := ghcontext.GetTokenInfo(ctx); ok {\n\t\t\t\t// Token info already exists in context, skip extraction\n\t\t\t\tnext.ServeHTTP(w, r)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttokenType, token, err := utils.ParseAuthorizationHeader(r)\n\t\t\tif err != nil {\n\t\t\t\t// For missing Authorization header, return 401 with WWW-Authenticate header per MCP spec\n\t\t\t\tif errors.Is(err, utils.ErrMissingAuthorizationHeader) {\n\t\t\t\t\tsendAuthChallenge(w, r, oauthCfg)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// For other auth errors (bad format, unsupported), return 400\n\t\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tctx = ghcontext.WithTokenInfo(ctx, &ghcontext.TokenInfo{\n\t\t\t\tToken:     token,\n\t\t\t\tTokenType: tokenType,\n\t\t\t})\n\t\t\tr = r.WithContext(ctx)\n\n\t\t\tnext.ServeHTTP(w, r)\n\t\t})\n\t}\n}\n\n// sendAuthChallenge sends a 401 Unauthorized response with WWW-Authenticate header\n// containing the OAuth protected resource metadata URL as per RFC 6750 and MCP spec.\nfunc sendAuthChallenge(w http.ResponseWriter, r *http.Request, oauthCfg *oauth.Config) {\n\tresourcePath := oauth.ResolveResourcePath(r, oauthCfg)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/http/middleware/token.go#L16-L52","documentation":"The 400 written when the Authorization header uses the non-standard 'GitHub-Bearer ' scheme, which ParseAuthorizationHeader explicitly refuses with ErrUnsupportedAuthorizationHeader ('bad request: unsupported Authorization header'). The sentinel is reserved for this scheme - the server intentionally does not decrypt GitHub-Bearer payloads; all other unrecognized formats land in the badly-formatted bucket instead.","triggerScenarios":"Sending 'Authorization: GitHub-Bearer <blob>' - e.g. replaying a header captured from GitHub's own first-party clients, or a client library/proxy defaulting to that scheme name.","commonSituations":"Copy-pasting auth schemes from other GitHub tooling; internal proxies rewriting the Authorization scheme; security tools replaying captured headers.","solutions":["Use the standard 'Authorization: Bearer <token>' form ('bearer' lowercase is also accepted)","Remove or fix any proxy that rewrites the scheme name","Confirm the HTTP client sets the header verbatim without scheme translation"],"exampleFix":"# before\nAuthorization: GitHub-Bearer AbCdEf...\n\n# after\nAuthorization: Bearer ghp_AbCdEf...","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(authHeader, \"GitHub-Bearer \") {\n\treturn errors.New(\"unsupported scheme: use 'Authorization: Bearer <token>'\")\n}\nreq.Header.Set(\"Authorization\", \"Bearer \"+token)","typeGuard":"func isUnsupportedAuthHeader(err error) bool {\n\treturn errors.Is(err, utils.ErrUnsupportedAuthorizationHeader)\n}","tryCatchPattern":"if _, _, err := utils.ParseAuthorizationHeader(req); err != nil {\n\tif errors.Is(err, utils.ErrUnsupportedAuthorizationHeader) {\n\t\t// specifically the GitHub-Bearer scheme: tell the client to switch to plain Bearer\n\t}\n}","preventionTips":["Always use the standard Bearer scheme ('bearer' case is accepted)","Ensure proxies do not rewrite or 'normalize' the Authorization scheme name","Do not replay headers captured from GitHub's first-party clients"],"tags":["http","authentication","token","middleware","scheme"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}