{"record":{"id":"56c8fde511308a87","repo":"golang/go","slug":"invalid-response-from-proxy-q-w","errorCode":null,"errorMessage":"invalid response from proxy %q: %w","messagePattern":"invalid response from proxy %q: %w","errorType":"exception","errorClass":"module.VersionError","httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/proxy.go","lineNumber":380,"sourceCode":"\t\treturn nil, p.versionError(\"\", codehost.ErrNoCommits)\n\t}\n\n\t// Call Stat to get all the other fields, including Origin information.\n\treturn p.Stat(ctx, bestVersion)\n}\n\nfunc (p *proxyRepo) Stat(ctx context.Context, rev string) (*RevInfo, error) {\n\tencRev, err := module.EscapeVersion(rev)\n\tif err != nil {\n\t\treturn nil, p.versionError(rev, err)\n\t}\n\tdata, err := p.getBytes(ctx, \"@v/\"+encRev+\".info\")\n\tif err != nil {\n\t\treturn nil, p.versionError(rev, err)\n\t}\n\tinfo := new(RevInfo)\n\tif err := json.Unmarshal(data, info); err != nil {\n\t\treturn nil, p.versionError(rev, fmt.Errorf(\"invalid response from proxy %q: %w\", p.redactedBase, err))\n\t}\n\tif info.Version != rev && rev == module.CanonicalVersion(rev) && module.Check(p.path, rev) == nil {\n\t\t// If we request a correct, appropriate version for the module path, the\n\t\t// proxy must return either exactly that version or an error — not some\n\t\t// arbitrary other version.\n\t\treturn nil, p.versionError(rev, fmt.Errorf(\"proxy returned info for version %s instead of requested version\", info.Version))\n\t}\n\treturn info, nil\n}\n\nfunc (p *proxyRepo) Latest(ctx context.Context) (*RevInfo, error) {\n\tdata, err := p.getBytes(ctx, \"@latest\")\n\tif err != nil {\n\t\tif !errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn nil, p.versionError(\"\", err)\n\t\t}\n\t\treturn p.latest(ctx)\n\t}","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/proxy.go#L362-L398","documentation":"proxyRepo.Stat unmarshals the JSON body of `@v/{encRev}.info` into a RevInfo. If the proxy returns non-JSON or malformed JSON, json.Unmarshal fails and the error is wrapped with the proxy's redacted base URL for diagnosis.","triggerScenarios":"getBytes succeeds (200 OK) but body is HTML error page, partial JSON, wrong content type, or otherwise invalid; json.Unmarshal returns non-nil.","commonSituations":"Corporate proxy returning an HTML login/captive portal; proxy returning a 200 with an error envelope; misbehaving self-hosted proxy; transient CDN corruption.","solutions":["Inspect what the proxy actually returned: curl -i {proxy}/{module}/@v/{ver}.info.","Bypass the failing proxy: GOPROXY=direct or GONOPROXY for the path.","If you operate the proxy, ensure .info returns strict JSON: {\"Version\":\"...\",\"Time\":\"...\",\"Origin\":{...}}.","Add the proxy host to NO_PROXY if it is intercepting all traffic unintentionally."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Smoke-test the .info endpoint before relying on Stat in automation.\nfunc probeInfo(proxy, mod, ver string) error {\n    resp, err := http.Get(proxy + \"/\" + mod + \"/@v/\" + ver + \".info\")\n    if err != nil { return err }\n    defer resp.Body.Close()\n    var v struct{ Version, Time string }\n    return json.NewDecoder(resp.Body).Decode(&v)\n}","typeGuard":null,"tryCatchPattern":"_, err := repo.Stat(ctx, rev)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid response from proxy\") {\n        // fall back to direct or another proxy entry\n    }\n}","preventionTips":["Use a conformant HTTPS proxy such as proxy.golang.org.","Watch for captive portals / corporate TLS intercept on the proxy host."],"tags":["goproxy","json","proxy","stat"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}