github/github-mcp-server · error · utils.ErrBadAuthorizationHeader
bad request: Authorization header is badly formatted
Error message
bad request: Authorization header is badly formatted
What it means
This is the 400 response the token middleware writes via http.Error(w, err.Error(), 400) when ParseAuthorizationHeader fails with a non-missing-header problem and the rendered text is 'bad request: Authorization header is badly formatted' - the mark.ErrBadRequest prefix ('bad request') plus the sentinel from pkg/utils/token.go. Concretely: the header was present, but the token matched no supported GitHub format (ghp_, github_pat_, gho_, ghu_, ghs_, or legacy 40-hex).
Source
Thrown at pkg/http/middleware/token.go:34
ctx := r.Context()
// Check if token info already exists in context, if it does, skip extraction.
// In remote setup, we may have already extracted token info earlier.
if _, ok := ghcontext.GetTokenInfo(ctx); ok {
// Token info already exists in context, skip extraction
next.ServeHTTP(w, r)
return
}
tokenType, token, err := utils.ParseAuthorizationHeader(r)
if err != nil {
// For missing Authorization header, return 401 with WWW-Authenticate header per MCP spec
if errors.Is(err, utils.ErrMissingAuthorizationHeader) {
sendAuthChallenge(w, r, oauthCfg)
return
}
// For other auth errors (bad format, unsupported), return 400
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
ctx = ghcontext.WithTokenInfo(ctx, &ghcontext.TokenInfo{
Token: token,
TokenType: tokenType,
})
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
}
// sendAuthChallenge sends a 401 Unauthorized response with WWW-Authenticate header
// containing the OAuth protected resource metadata URL as per RFC 6750 and MCP spec.
func sendAuthChallenge(w http.ResponseWriter, r *http.Request, oauthCfg *oauth.Config) {
resourcePath := oauth.ResolveResourcePath(r, oauthCfg)View on GitHub (pinned to 0ea1f775a7)
Solutions
- Log a safe prefix (first 4 chars) of the token being sent to confirm which value reaches the server
- Replace with a supported GitHub token type (ghp_/github_pat_/gho_/ghu_/ghs_)
- Verify secret interpolation - an unexpanded ${VAR} or $VAR literal in the value is a classic cause
Example fix
# before
Authorization: Bearer ${GITHUB_TOKEN} # unexpanded placeholder
# after
Authorization: Bearer ghp_xxxx # properly interpolated real token Defensive patterns
Strategy: validation
Validate before calling
var gitHubTokenRe = regexp.MustCompile(`^(ghp_|github_pat_|gho_|ghu_|ghs_)[A-Za-z0-9_]+$|^[a-f0-9]{40}$`)
if !gitHubTokenRe.MatchString(token) {
return errors.New("token does not look like a GitHub token; server will answer 400 badly formatted")
}
req.Header.Set("Authorization", "Bearer "+token) Type guard
func isBadAuthHeader(err error) bool {
return errors.Is(err, utils.ErrBadAuthorizationHeader)
} Try / catch
// middleware shape: distinguish the three auth sentinels before choosing a status
if err != nil {
switch {
case errors.Is(err, utils.ErrMissingAuthorizationHeader):
sendAuthChallenge(w, r) // 401 + WWW-Authenticate
case errors.Is(err, utils.ErrBadAuthorizationHeader), errors.Is(err, utils.ErrUnsupportedAuthorizationHeader):
http.Error(w, err.Error(), http.StatusBadRequest)
}
} Prevention
- Verify secret interpolation actually expanded before the request leaves CI
- Log a safe token prefix (first 4 chars) client-side to catch placeholder leaks
- Distinguish 400 (fix the token) from 401 (run the OAuth flow) in error handling
When it happens
Trigger: Authorization: Bearer <token> where the token is a placeholder, another vendor's credential, an unexpanded ${GITHUB_TOKEN} literal, or otherwise prefix-unknown.
Common situations: Example tokens left in committed configs; env interpolation failing in CI so the literal placeholder is sent; tokens truncated by column limits when copied out of logs/secrets.
Related errors
- %w: Authorization header is badly formatted
- bad request: unsupported Authorization header
- App not connected
- bad request
- %w: missing required Authorization header
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/e9707a2bbfe124b1.
Report an issue: GitHub.