googleapis/mcp-toolbox · error
failed to construct introspection URL: %w
Error message
failed to construct introspection URL: %w
What it means
When no explicit introspection URL is configured, validateOpaqueToken derives one by joining the configured AuthorizationServer base URL with the 'introspect' path using url.JoinPath. If the join fails (malformed base URL, control characters, invalid escape), the library wraps the error with this message and aborts validation.
Source
Thrown at internal/auth/generic/generic.go:353
err = a.validateClaims(ctx, iss, aud, scopeClaim)
if err != nil {
return nil, err
}
return claims, nil
}
// validateOpaqueToken validates an opaque token by calling the introspection endpoint
func (a AuthService) validateOpaqueToken(ctx context.Context, tokenStr string) (map[string]any, error) {
logger, err := util.LoggerFromContext(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get logger from context: %w", err)
}
introspectionURL := a.introspectionURL
if introspectionURL == "" {
introspectionURL, err = url.JoinPath(a.AuthorizationServer, "introspect")
if err != nil {
return nil, fmt.Errorf("failed to construct introspection URL: %w", err)
}
}
paramName := a.IntrospectionParamName
if paramName == "" {
paramName = "token"
}
var req *http.Request
if a.IntrospectionMethod == "GET" {
u, err := url.Parse(introspectionURL)
if err != nil {
return nil, fmt.Errorf("failed to parse introspection URL: %w", err)
}
q := u.Query()
q.Set(paramName, tokenStr)
u.RawQuery = q.Encode()
req, err = http.NewRequestWithContext(ctx, "GET", u.String(), nil)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Check the configured authorizationServer/authUrl value and fix the malformed base URL (include scheme, valid host).
- Echo/print the resolved env var to catch stray spaces, quotes, or newline characters.
- Alternatively set the explicit introspection URL in the auth config to bypass JoinPath derivation.
Example fix
// before genericAuth: authorizationServer: "idp.example.com/oauth2" # missing scheme // after genericAuth: authorizationServer: "https://idp.example.com/oauth2"
Defensive patterns
Strategy: validation
Validate before calling
base := cfg.AuthorizationServer
u, err := url.Parse(base)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("authorizationServer %q is not a valid absolute URL", base)
} Type guard
func isValidAbsoluteURL(s string) bool {
u, err := url.Parse(s)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
claims, err := svc.ValidateMCPAuth(ctx, header)
if err != nil {
if strings.Contains(err.Error(), "failed to construct introspection URL") {
log.Fatalf("bad authorizationServer config: %v", err) // startup config bug, not runtime
}
return claims, err
} Prevention
- Validate the auth URL config at startup with url.Parse
- Always include the https:// scheme in configuration values
- Quote env vars in shell/YAML to avoid injected whitespace
When it happens
Trigger: AuthService.Config.IntrospectionURL is empty and url.JoinPath(a.AuthorizationServer, "introspect") returns an error, e.g. AuthorizationServer set to an invalid value like 'http://[::1' or containing control characters.
Common situations: Typo or truncation in the AuthorizationServer config value, environment variable interpolation injecting whitespace or quotes, or forgetting the scheme (e.g. 'idp.example.com' instead of 'https://idp.example.com').
Related errors
- failed to parse introspection URL: %w
- unable to initialize server: %w
- failed to read manual PRM file at startup: %w
- error building req for endpoint [%v] : %v
- failed to parse BaseUrl %v
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/203527ba39b92931.
Report an issue: GitHub.