{"record":{"id":"dcb63032a2bffedf","repo":"go-kratos/kratos","slug":"response-error-d","errorCode":null,"errorMessage":"response Error %d","messagePattern":"response Error (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"contrib/registry/eureka/client.go","lineNumber":348,"sourceCode":"\t}\n\tdefer func() {\n\t\t_, _ = io.Copy(io.Discard, resp.Body)\n\t\t_ = resp.Body.Close()\n\t}()\n\n\tif output != nil && resp.StatusCode/100 == 2 {\n\t\tdata, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\terr = json.Unmarshal(data, output)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t}\n\n\tif resp.StatusCode >= http.StatusBadRequest {\n\t\treturn false, fmt.Errorf(\"response Error %d\", resp.StatusCode)\n\t}\n\n\treturn false, nil\n}\n\nfunc (e *Client) do(ctx context.Context, method string, params []string, input io.Reader, output any) error {\n\tfor i := 0; i < e.maxRetry; i++ {\n\t\tretry, err := e.request(ctx, method, params, input, output, i)\n\t\tif retry {\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"retry after %d times\", e.maxRetry)\n}","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/contrib/registry/eureka/client.go#L330-L366","documentation":"Returned by the Kratos Eureka registry client when the Eureka server answers an HTTP request with status >= 400 (http.StatusBadRequest). Note this error path is NOT retried: request() returns retry=false, so do() fails immediately even though maxRetry is configured; only transport-level failures are retried. The value is the raw HTTP status code with no response body details.","triggerScenarios":"Any Client.do() operation (Register, Deregister, Heartbeat/heartbeat via applications API, GetApplication, UpdateMetadata) receiving a 4xx/5xx: 404 when querying an app or instance not yet registered, 400 for a malformed JSON body (e.g. non-JSON instance payload), 403 when Eureka has auth enabled but credentials are missing, 500/503 when Eureka is unhealthy or throttling.","commonSituations":"Heartbeat racing deregistration (404 on instance); eureka server path prefix (eurekaPath) misconfigured so URLs hit a non-existent route (404); sending a plain Go struct instead of proper JSON; Eureka behind a proxy returning 502/503; auth (basic auth) not configured on the eureka client.","solutions":["Reproduce the exact URL from the error context (server + eurekaPath + operation path) with curl and inspect the Eureka response body for the real cause","Verify the eureka server URL and eurekaPath configuration (commonly /eureka) match your server, including any context path or reverse-proxy prefix","For 404 on instance operations, ensure Register completed before heartbeat/deregister, and that instanceID matches what Eureka assigned","For 401/403, configure the credentials/auth on the eureka client if the server requires them","For 5xx, check Eureka server health/logs (it may be in self-preservation or out of resources) and rely on caller-level retry since the client will not retry status errors"],"exampleFix":"// before: wrong path prefix yields 404 \"response Error 404\"\nclient := eureka.NewClient(&eureka.Config{Servers: []string{\"http://eureka:8761\"}})\n\n// after: include the eureka context path\nclient := eureka.NewClient(&eureka.Config{Servers: []string{\"http://eureka:8761/eureka\"}})","handlingStrategy":"try-catch","validationCode":"// Verify the eureka base config before first use\nfunc checkEureka(cfg *eureka.Config) error {\n\tif len(cfg.Servers) == 0 {\n\t\treturn fmt.Errorf(\"no eureka servers configured\")\n\t}\n\tfor _, s := range cfg.Servers {\n\t\tu, err := url.Parse(s)\n\t\tif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n\t\t\treturn fmt.Errorf(\"bad eureka server URL %q\", s)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"err := client.Register(ctx, ins)\nif err != nil {\n\tvar msg string\n\tif errors.As(err, &msg); strings.HasPrefix(err.Error(), \"response Error \") {\n\t\tcode := strings.TrimSpace(strings.TrimPrefix(err.Error(), \"response Error\"))\n\t\tswitch code {\n\t\tcase \"404\": // instance/app unknown: register first or ignore\n\t\tcase \"401\", \"403\": // fix credentials, do not retry\n\t\tdefault: // 5xx: server-side, safe to retry with backoff\n\t\t}\n\t}\n}","preventionTips":["Smoke-test one full register/get cycle against Eureka in CI to catch path/auth mistakes","Keep the eurekaPath consistent with the server's context path in all environments","Register before scheduling heartbeats and stop heartbeats before deregistering to avoid 404 races","Remember the client does NOT retry 4xx/5xx - put retry-with-backoff at the call site for transient 5xx"],"tags":["go","kratos","eureka","service-registry","http"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}