github/github-mcp-server · error · mark.ErrBadRequest
%w: missing required Authorization header
Error message
%w: missing required Authorization header
What it means
Sentinel error returned by utils.ParseAuthorizationHeader when the request carries no Authorization header at all. Although it wraps mark.ErrBadRequest ('bad request'), the token middleware special-cases it: instead of a 400 it calls sendAuthChallenge, producing a 401 with a WWW-Authenticate Bearer challenge per the MCP authorization spec so OAuth clients start the flow.
Source
Thrown at pkg/utils/token.go:33
const (
TokenTypeUnknown TokenType = iota
TokenTypePersonalAccessToken
TokenTypeFineGrainedPersonalAccessToken
TokenTypeOAuthAccessToken
TokenTypeUserToServerGitHubAppToken
TokenTypeServerToServerGitHubAppToken
)
var supportedGitHubPrefixes = map[string]TokenType{
"ghp_": TokenTypePersonalAccessToken, // Personal access token (classic)
"github_pat_": TokenTypeFineGrainedPersonalAccessToken, // Fine-grained personal access token
"gho_": TokenTypeOAuthAccessToken, // OAuth access token
"ghu_": TokenTypeUserToServerGitHubAppToken, // User access token for a GitHub App
"ghs_": TokenTypeServerToServerGitHubAppToken, // Installation access token for a GitHub App (a.k.a. server-to-server token)
}
var (
ErrMissingAuthorizationHeader = fmt.Errorf("%w: missing required Authorization header", mark.ErrBadRequest)
ErrBadAuthorizationHeader = fmt.Errorf("%w: Authorization header is badly formatted", mark.ErrBadRequest)
ErrUnsupportedAuthorizationHeader = fmt.Errorf("%w: unsupported Authorization header", mark.ErrBadRequest)
)
// oldPatternRegexp is the regular expression for the old pattern of the token.
// Until 2021, GitHub API tokens did not have an identifiable prefix. They
// were 40 characters long and only contained the characters a-f and 0-9.
var oldPatternRegexp = regexp.MustCompile(`\A[a-f0-9]{40}\z`)
// ParseAuthorizationHeader parses the Authorization header from the HTTP request
func ParseAuthorizationHeader(req *http.Request) (tokenType TokenType, token string, _ error) {
authHeader := req.Header.Get(httpheaders.AuthorizationHeader)
if authHeader == "" {
return 0, "", ErrMissingAuthorizationHeader
}
switch {
// decrypt dotcom token and set it as tokenView on GitHub (pinned to 0ea1f775a7)
Solutions
- Send Authorization: Bearer <GitHub token> on every request to protected endpoints
- As an OAuth client, treat the 401 + WWW-Authenticate response as the trigger to run the OAuth flow, then retry
- Check intermediaries (nginx auth_request, meshes, gateways) are not stripping Authorization
Example fix
# before curl http://localhost:8080/api/mcp -d @req.json # after curl http://localhost:8080/api/mcp -H "Authorization: Bearer ghp_xxxx" -d @req.json
Defensive patterns
Strategy: validation
Validate before calling
// client side, before sending
if token == "" {
return errors.New("no token configured: the server will answer 401 with a Bearer challenge")
}
req.Header.Set("Authorization", "Bearer "+token) Type guard
func isMissingAuthHeader(err error) bool {
return errors.Is(err, utils.ErrMissingAuthorizationHeader)
} Try / catch
if err != nil {
if errors.Is(err, utils.ErrMissingAuthorizationHeader) {
// middleware already sent 401 + WWW-Authenticate: start/continue the OAuth flow, then retry
} else {
// 400-class header problems: fix the token, do not challenge
}
} Prevention
- Set the token once on the client transport (DefaultHeader/SetAuthToken) so every call carries it
- Treat 401 + WWW-Authenticate as a flow trigger, not a hard failure
- Smoke-test endpoints with an authenticated request in CI
When it happens
Trigger: Any HTTP request to a token-protected endpoint without an Authorization header: bare curl, an MCP client with no token configured, or a proxy that strips the header.
Common situations: First requests from remote MCP clients before OAuth completes; curl tests forgetting -H 'Authorization: Bearer ...'; reverse proxies or service meshes dropping the header.
Related errors
- App not connected
- %w: Authorization header is badly formatted
- Forbidden: insufficient scopes
- bad request: Authorization header is badly formatted
- bad request: unsupported Authorization header
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/093e6b241a5d72df.
Report an issue: GitHub.