{"record":{"id":"6a09ff55ad498e47","repo":"go-kratos/kratos","slug":"retry-after-d-times","errorCode":null,"errorMessage":"retry after %d times","messagePattern":"retry after (.+?) times","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"contrib/registry/eureka/client.go","lineNumber":365,"sourceCode":"\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}\n","sourceCodeStart":347,"sourceCodeEnd":367,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/contrib/registry/eureka/client.go#L347-L367","documentation":"Returned by the Kratos Eureka client's do() loop after every one of the maxRetry attempts signaled retry=true. retry=true only happens when e.client.Do(request) itself fails (connection refused, DNS failure, timeout, TLS error) at client.go:328-329; each attempt also rotates to the next server URL via pickServer. So this error means every configured Eureka server URL was unreachable at the transport level. Note the final error discards the underlying cause - only the retry count is reported, so check logs/network for the real reason.","triggerScenarios":"All servers in the Config.Servers list are down or unreachable: connection refused (server not listening on that port), DNS name not resolvable, network partition/firewall blocking the port, TLS handshake failure on https URLs, or request context deadline exceeded repeatedly. Also triggered if Servers list is effectively all the same broken host and maxRetry (default 3) attempts all fail.","commonSituations":"Wrong server address/port in Kubernetes ConfigMap; Eureka pod not ready when the app starts (no startup retry at caller level); DNS entry missing in the environment; security group blocking egress to the Eureka port; https URL with a cert the client cannot validate.","solutions":["From the app container, verify reachability of every configured server: curl http://<server>/eureka/apps or a TCP check on the port; fix address/port/DNS/firewall as needed","Check whether the Eureka instance(s) are actually running and ready (pod status, health endpoint) - if this fires at startup, add readiness gating or startup retry for the registrar","If multiple servers are configured, confirm each entry is individually valid; pickServer cycles through urls[maxRetry] entries, so a bad list wastes all attempts","Add caller-level retry with backoff around Register/heartbeat operations, since do() only retries transport errors within one call","Increase visibility: capture the underlying transport error (tcp timeout vs refused vs TLS) from logs or a manual request before blaming the client"],"exampleFix":"// before: single wrong port; every retry fails -> \"retry after 3 times\"\ncfg := &eureka.Config{Servers: []string{\"http://eureka:8760/eureka\"}}\n\n// after: correct port plus more fallback servers\ncfg := &eureka.Config{Servers: []string{\"http://eureka-1:8761/eureka\", \"http://eureka-2:8761/eureka\"}}","handlingStrategy":"retry","validationCode":"// Fail fast if no server URL is reachable before starting the registrar\nfunc reachable(servers []string, path string) error {\n\tfor _, s := range servers {\n\t\tresp, err := http.Get(s + path) //nolint:gosec\n\t\tif err == nil {\n\t\t\t_ = resp.Body.Close()\n\t\t\tif resp.StatusCode < 500 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\treturn fmt.Errorf(\"no eureka server reachable: %v\", servers)\n}","typeGuard":null,"tryCatchPattern":"var err error\nfor attempt := 0; attempt < 3; attempt++ {\n\tif err = client.Register(ctx, ins); err == nil {\n\t\tbreak\n\t}\n\tif !strings.Contains(err.Error(), \"retry after\") { // only transport exhaustion is retried\n\t\tbreak\n\t}\n\tselect {\n\tcase <-time.After(time.Duration(attempt+1) * time.Second):\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n}","preventionTips":["Configure multiple Eureka server URLs spread across zones so pickServer has real fallbacks","Gate app startup on Eureka readiness (readiness probe or startup check) so first registration does not race an unready server","Verify DNS and egress firewall rules to the Eureka port from every deployment environment","Export the underlying transport error in your own wrapper when logging - 'retry after N times' hides the root cause"],"tags":["go","kratos","eureka","service-registry","network","retry"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}