github/github-mcp-server · error
failed to fetch raw content: %s
Error message
failed to fetch raw content: %s
What it means
The raw content endpoint for a repo:// resource returned a status other than 200 or 404, and this error embeds the raw response body verbatim via %s. Typical bodies are GitHub's error documents: 401 'Bad credentials' (expired/revoked token), 403 rate limit or blocked repo, or 5xx from the raw CDN. The message omits the HTTP status code, so the cause must be inferred from the body text.
Source
Thrown at pkg/github/repository_resource.go:254
}
return &mcp.ReadResourceResult{
Contents: []*mcp.ResourceContents{
{
URI: request.Params.URI,
MIMEType: mimeType,
Blob: buf.Bytes(),
},
},
}, nil
}
case resp.StatusCode != http.StatusNotFound:
// If we got a response but it is not 200 OK, we return an error
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
return nil, fmt.Errorf("failed to fetch raw content: %s", string(body))
default:
// This should be unreachable because GetContents should return an error if neither file nor directory content is found.
return nil, errors.New("404 Not Found")
}
}
}
// expandRepoResourceURI builds a resource URI using the appropriate URI template
// based on the provided parameters (sha, ref, or default).
func expandRepoResourceURI(owner, repo, sha, ref string, pathParts []string) (string, error) {
baseValues := uritemplate.Values{
"owner": uritemplate.String(owner),
"repo": uritemplate.String(repo),
"path": uritemplate.List(pathParts...),
}
switch {
case sha != "":View on GitHub (pinned to 0ea1f775a7)
Solutions
- Read the embedded body: 'Bad credentials' means rotate/refresh the token; 'rate limit' means back off and respect Retry-After
- Verify the token against raw content directly: curl -H "Authorization: Bearer $TOKEN" https://raw.githubusercontent.com/owner/repo/main/README.md
- For 403 secondary rate limits, wait and retry with exponential backoff
- Improve the handler to prefix resp.Status so triage does not depend on parsing the body
Example fix
// before
return nil, fmt.Errorf("failed to fetch raw content: %s", string(body))
// after - keep the status code and trim the body
return nil, fmt.Errorf("failed to fetch raw content: %s: %s", resp.Status, bytes.TrimSpace(body)) Defensive patterns
Strategy: try-catch
Validate before calling
// Fail fast before bulk raw reads: verify the token and rate-limit headroom
rl, resp, err := client.RateLimit.Get(ctx)
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("token or API unusable, aborting raw reads: %v", err)
}
if rl.GetCore().Remaining == 0 {
return fmt.Errorf("rate limit exhausted until %v", rl.GetCore().Reset.Time)
} Type guard
func classifyRawContentError(msg string) string {
switch {
case strings.Contains(msg, "Bad credentials"):
return "invalid-token"
case strings.Contains(msg, "rate limit"), strings.Contains(msg, "secondary rate limit"):
return "rate-limited"
case strings.Contains(msg, "404"):
return "not-found"
default:
return "unknown"
}
} Try / catch
result, err := readResource(ctx, uri)
if err != nil && strings.HasPrefix(err.Error(), "failed to fetch raw content") {
switch classifyRawContentError(err.Error()) {
case "invalid-token":
return errors.New("raw content token expired or revoked; refresh it")
case "rate-limited":
time.Sleep(time.Until(resetAt)) // then retry
default:
return err
}
} Prevention
- Rotate tokens before expiry so raw fetches never send dead credentials
- Respect Retry-After and x-ratelimit-reset on 403/429 before more raw reads
- Keep GH_HOST/raw host configuration consistent with the token's instance (github.com vs GHE)
When it happens
Trigger: Expired or revoked PAT on raw.githubusercontent.com; secondary rate limit (403 'You have exceeded a secondary rate limit') from aggressive raw fetches; private repo the token cannot read; 5xx incident on the raw CDN; wrong raw host for GH_HOST/GHE configurations.
Common situations: Long-running servers whose token expired mid-session; CI jobs fetching many raw files and tripping abuse detection; misconfigured GH_HOST so raw requests go to a host that rejects them.
Related errors
- failed to get issue ID: %w
- failed to get issue: %w
- failed to list releases: %w
- failed to read file content: %w
- failed to read response body: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/e8dcc29694d19712.
Report an issue: GitHub.