{"record":{"id":"cfe76581646f6b0c","repo":"fatedier/frp","slug":"api-status-code-d","errorCode":null,"errorMessage":"api status code [%d]","messagePattern":"api status code \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/sdk/client/client.go","lineNumber":133,"sourceCode":"}\n\nfunc (c *Client) setAuthHeader(req *http.Request) {\n\tif c.authUser != \"\" || c.authPwd != \"\" {\n\t\treq.Header.Set(\"Authorization\", httppkg.BasicAuth(c.authUser, c.authPwd))\n\t}\n}\n\nfunc (c *Client) do(req *http.Request) (string, error) {\n\tc.setAuthHeader(req)\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn \"\", fmt.Errorf(\"api status code [%d]\", resp.StatusCode)\n\t}\n\tbuf, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(buf), nil\n}\n","sourceCodeStart":115,"sourceCodeEnd":141,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/sdk/client/client.go#L115-L141","documentation":"Returned by Client.do, the shared transport for all SDK calls, whenever the frpc admin API answers with a non-200 status. The message contains only the numeric code, e.g. \"api status code [401]\", and applies to every endpoint (status, reload, stop, config).","triggerScenarios":"401 when the auth token/user/password does not match frpc webServer credentials; 404 when the path is served by a different service or an older frpc without that endpoint; 500 when frpc fails internally (e.g. reload with invalid config).","commonSituations":"SDK client created without or with the wrong auth credentials vs webServer.user/password in frpc.toml; querying a newer API endpoint against an older frpc; strict-mode reload rejecting the config and surfacing as 500.","solutions":["Decode the status: 401 → set matching webServer credentials on the SDK client; 404 → wrong address or endpoint missing in this frpc version; 500 → inspect frpc logs for the server-side cause.","Confirm webServer.user/webServer.password in frpc.toml and pass the same values when constructing the client.","Upgrade the SDK client and frpc to the same release so endpoint paths and auth behavior agree."],"exampleFix":"// before\nclient := client.New(\"127.0.0.1:7400\") // no auth → 401\n\n// after\nclient := client.New(\"127.0.0.1:7400\")\nclient.SetAuth(\"admin\", \"strong-password\") // must equal webServer.user / webServer.password","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := client.GetAllProxyStatus(ctx); err != nil {\n    if m := regexp.MustCompile(`api status code \\[(\\d+)\\]`).FindStringSubmatch(err.Error()); m != nil {\n        switch m[1] {\n        case \"401\": // fix webServer credentials on the client\n        case \"404\": // wrong address or endpoint missing in this frpc version\n        default:   // check frpc logs for server-side failure\n        }\n    }\n    return err\n}","preventionTips":["Set the SDK client's auth to the same webServer.user/password as frpc.toml.","Match SDK and frpc versions in CI so endpoint paths always agree.","Treat 5xx from /api/reload as a config problem: validate config before reloading."],"tags":["sdk","http","auth","frpc-admin","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}