{"record":{"id":"d472b602b2c242c2","repo":"juicedata/juicefs","slug":"error-get-request-status-code-d","errorCode":null,"errorMessage":"error GET request, status code %d","messagePattern":"error GET request, status code (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/debug.go","lineNumber":234,"sourceCode":"\tif listenPort == -1 {\n\t\treturn 0, fmt.Errorf(\"no valid pprof port found\")\n\t}\n\treturn listenPort, nil\n}\n\nfunc getRequest(url string, timeout time.Duration) ([]byte, error) {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating GET request: %v\", err)\n\t}\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error GET request: %v\", err)\n\t}\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"error GET request, status code %d\", resp.StatusCode)\n\t}\n\n\tdefer func(body io.ReadCloser) {\n\t\tif err := body.Close(); err != nil {\n\t\t\tlogger.Errorf(\"error closing body: %v\", err)\n\t\t}\n\t}(resp.Body)\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading response: %v\", err)\n\t}\n\n\treturn body, nil\n}\n\n// check pprof service status\nfunc checkPort(port int, amp string) error {\n\turl := fmt.Sprintf(\"http://localhost:%d/debug/pprof/cmdline?debug=1\", port)","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/debug.go#L216-L252","documentation":"After the GET succeeds, getRequest rejects any response whose HTTP status is not exactly 200 and returns 'error GET request, status code %d'. This is an application-level rejection: the server answered, but not with the expected successful body — pprof endpoints and metric URLs return 200 for well-formed requests.","triggerScenarios":"Called from checkPort (cmdline probe) or reqAndSaveMetric when the target returns 404 (wrong pprof path or metric URL), 403 (auth/protection enabled on the endpoint, e.g. behind a proxy requiring credentials), 503/500 (endpoint crashed or overloaded), or a redirect-to-login (30x would actually be followed by DefaultClient and land on a non-200 page).","commonSituations":"A non-JuiceFS service occupies the discovered port (checkPort probes it blind and gets 404); pprof endpoint wrapped in an authenticated reverse proxy; metric URL typos after version changes; the mount process wedged so its pprof handler returns 500.","solutions":["Note the reported status code: 404 → wrong path/port; 403 → auth in front of the endpoint; 500 → check the JuiceFS client logs.","Verify the port really belongs to the JuiceFS process: `lsof -i :<port> -nP | grep <pid>`; kill or skip foreign services on 6060-6099.","Fetch the URL manually with `curl -i` to inspect headers/body and any proxy/auth challenge.","Disable or bypass proxies/auth for localhost pprof endpoints (NO_PROXY=localhost,127.0.0.1).","If a custom metric URL is used in reqAndSaveMetric, confirm it exists on the running JuiceFS version (URLs change between releases)."],"exampleFix":"// before\n// getRequest rejects any non-200, so a 404 from a foreign service looks opaque\n// after (caller-side check before probing)\nif out, err := exec.Command(\"lsof\", \"-i\", fmt.Sprintf(\":%d\", port), \"-nP\").CombinedOutput(); err != nil || !strings.Contains(string(out), \"juicefs\") {\n    return fmt.Errorf(\"port %d is not a juicefs listener\", port)\n}","handlingStrategy":"validation","validationCode":"resp, err := http.Head(u)\nif err != nil { return err }\nif resp.StatusCode != 200 {\n    return fmt.Errorf(\"endpoint %s answered %d; expected 200\", u, resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"body, err := getRequest(url, timeout)\nif err != nil {\n    var sc int\n    if _, serr := fmt.Sscanf(err.Error(), \"error GET request, status code %d\", &sc); serr == nil {\n        switch sc {\n        case 404: // wrong path/port — fix url or port discovery\n        case 403: // auth in front of endpoint — provide credentials/bypass proxy\n        default:  // inspect endpoint health\n        }\n        return err\n    }\n    return err\n}","preventionTips":["Check `curl -i` headers on the endpoint to see proxy/auth challenges before debugging.","Ensure only the JuiceFS process occupies 6060-6099 so probes don't hit foreign 404s.","Keep metric URLs in sync with the running JuiceFS version (paths change between releases).","Set NO_PROXY=localhost,127.0.0.1 so proxies don't inject 403/407 responses on pprof probes."],"tags":["go","http","http-status","pprof"],"backgroundTag":"http-non-200-response","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}