github/github-mcp-server · error
failed to parse API host: %w
Error message
failed to parse API host: %w
What it means
utils.NewAPIHost rejected cfg.Host: the string could not be parsed and normalized into the REST/GraphQL/upload/raw endpoint set. Hosts must be parseable URLs with a scheme - the dotcom constant or a GHES base URL.
Source
Thrown at pkg/http/server.go:130
var slogHandler slog.Handler
var logOutput io.Writer
if cfg.LogFilePath != "" {
file, err := os.OpenFile(cfg.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return fmt.Errorf("failed to open log file: %w", err)
}
logOutput = file
slogHandler = slog.NewTextHandler(logOutput, &slog.HandlerOptions{Level: slog.LevelDebug})
} else {
logOutput = os.Stderr
slogHandler = slog.NewTextHandler(logOutput, &slog.HandlerOptions{Level: slog.LevelInfo})
}
logger := slog.New(slogHandler)
logger.Info("starting server", "version", cfg.Version, "host", cfg.Host, "lockdownEnabled", cfg.LockdownMode, "readOnly", cfg.ReadOnly, "insidersMode", cfg.InsidersMode)
apiHost, err := utils.NewAPIHost(cfg.Host)
if err != nil {
return fmt.Errorf("failed to parse API host: %w", err)
}
hostType, err := utils.ParseHostType(cfg.Host)
if err != nil {
return fmt.Errorf("failed to classify API host: %w", err)
}
repoAccessOpts := []lockdown.RepoAccessOption{
lockdown.WithLogger(logger.With("component", "lockdown")),
}
if cfg.RepoAccessCacheTTL != nil {
repoAccessOpts = append(repoAccessOpts, lockdown.WithTTL(*cfg.RepoAccessCacheTTL))
}
featureChecker := createHTTPFeatureChecker(cfg.EnabledFeatures, cfg.InsidersMode)
obs, err := observability.NewExporters(logger, metrics.NewNoopMetrics())
if err != nil {
return fmt.Errorf("failed to create observability exporters: %w", err)View on GitHub (pinned to 0ea1f775a7)
Solutions
- Use https://api.github.com for dotcom, or the full https base URL of the GHES instance
- Ensure the scheme is present and there is no stray path, query, or whitespace
- Validate candidate host strings with utils.NewAPIHost in a smoke test before deploying
Example fix
// before cfg.Host = "github.example.com" // after cfg.Host = "https://github.example.com"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(cfg.Host)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("host must be an absolute URL like https://api.github.com, got %q", cfg.Host)
} Prevention
- Configure hosts as absolute https URLs
- Trim whitespace and quotes from env-provided host values
- Validate host strings with utils.NewAPIHost in config tests
When it happens
Trigger: Passing a bare hostname without a scheme (github.example.com), a URL with unexpected path/query components, control characters, or otherwise malformed URL syntax.
Common situations: Misconfigured GITHUB_API_URL or host flag values; copy-paste with trailing punctuation or whitespace; switching from hostname-style config to URL-style config.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to get base REST URL: %w
- failed to create default API host: %w
- failed to classify API host: %w
- authentication required: set GITHUB_PERSONAL_ACCESS_TOKEN, c
- GitHub App authentication and OAuth login (--oauth-client-id
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/f66234968dd94338.
Report an issue: GitHub.