{"record":{"id":"a24fad902a7a5e49","repo":"googleapis/mcp-toolbox","slug":"failed-to-read-google-tokeninfo-response-w","errorCode":null,"errorMessage":"failed to read Google tokeninfo response: %w","messagePattern":"failed to read Google tokeninfo response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/google/google.go","lineNumber":205,"sourceCode":"\n\tclient := a.client\n\tif client == nil {\n\t\tclient = http.DefaultClient\n\t}\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, &auth.MCPAuthError{Code: http.StatusInternalServerError, Message: fmt.Sprintf(\"failed to call Google tokeninfo: %v\", err), ScopesRequired: a.ScopesRequired}\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, &auth.MCPAuthError{Code: http.StatusUnauthorized, Message: fmt.Sprintf(\"Google token validation failed with status: %d\", resp.StatusCode), ScopesRequired: a.ScopesRequired}\n\t}\n\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read Google tokeninfo response: %w\", err)\n\t}\n\n\tvar tokenInfo struct {\n\t\tAud   string `json:\"aud\"`\n\t\tAzp   string `json:\"azp\"`\n\t\tScope string `json:\"scope\"`\n\t}\n\tif err := json.Unmarshal(body, &tokenInfo); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode Google tokeninfo response: %w\", err)\n\t}\n\n\taud := tokenInfo.Aud\n\tif aud == \"\" {\n\t\taud = tokenInfo.Azp\n\t}\n\n\taudLimit := a.Audience\n\tif audLimit == \"\" {","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/auth/google/google.go#L187-L223","documentation":"After a successful (HTTP 200) call to Google's tokeninfo endpoint, ValidateMCPAuth reads up to 1 MiB of the response body. If io.ReadAll fails (connection reset mid-read, context canceled, TLS error during body streaming), the error is wrapped with this message.","triggerScenarios":"Google tokeninfo response body read interrupted: network drop, ctx deadline exceeded during read, proxy closing connection prematurely.","commonSituations":"Flaky network or corporate proxy between the toolbox and oauth2.googleapis.com; request context timeout set too tight; transient GCP API incidents.","solutions":["Retry the request; tokeninfo reads are usually transient failures","Increase the request/context timeout","Check proxy/firewall stability for oauth2.googleapis.com","Verify network egress in the deployment environment"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"claims, err := svc.ValidateMCPAuth(ctx, h)\nif err != nil && strings.Contains(err.Error(), \"failed to read Google tokeninfo response\") {\n    time.Sleep(200 * time.Millisecond)\n    claims, err = svc.ValidateMCPAuth(ctx, h) // retry once on transient read failure\n}","preventionTips":["Set generous but bounded context timeouts for auth validation","Ensure stable egress to oauth2.googleapis.com (no aggressive idle-timeout proxies)","Add retry with backoff around token validation in middleware","Monitor Google tokeninfo endpoint availability"],"tags":["go","auth","google","network","io"],"backgroundTag":"http-response-read-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}