{"record":{"id":"8c6ff14466402bdb","repo":"hyperledger/fabric","slug":"retry-attempts-exhausted","errorCode":null,"errorMessage":"retry attempts exhausted","messagePattern":"retry attempts exhausted","errorType":"exception","errorClass":"ErrRetryCountExhausted","httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/deliver.go","lineNumber":643,"sourceCode":"\t\t}, nil\n\t}\n}\n\ntype errorAndResponse struct {\n\terr  error\n\tresp *orderer.DeliverResponse\n}\n\n// ErrForbidden denotes that an ordering node refuses sending blocks due to access control.\nvar ErrForbidden = errors.New(\"forbidden pulling the channel\")\n\n// ErrServiceUnavailable denotes that an ordering node is not servicing at the moment.\nvar ErrServiceUnavailable = errors.New(\"service unavailable\")\n\n// ErrNotInChannel denotes that an ordering node is not in the channel\nvar ErrNotInChannel = errors.New(\"not in the channel\")\n\nvar ErrRetryCountExhausted = errors.New(\"retry attempts exhausted\")\n","sourceCodeStart":625,"sourceCodeEnd":644,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/deliver.go#L625-L644","documentation":"ErrRetryCountExhausted is returned when the retry mechanism gave up: pullUntilTarget exceeded its retry attempts without reaching the target block, or GetLatestConfigBlock in util.go exhausted endpoint retries (endpoint == \"\") or the pulled last block came back nil. It means the cluster node could not be reached or made no progress within the allowed retries.","triggerScenarios":"pullUntilTarget loops past its maximum retry count; util.go:788 — after retrying all endpoints, no endpoint remains (endpoint == \"\"); util.go:792 — PullBlock returned nil because all pull attempts failed.","commonSituations":"All ordering endpoints unreachable during eviction detection; persistent network outage or TLS misconfiguration to every cluster member; retry/total timeout configuration too small for a slow cluster; channel stuck because the local node is behind and cannot pull config blocks.","solutions":["Verify network reachability and TLS trust to all configured cluster endpoints","Increase retry-related configuration (retry budget, total time budget) in General.Cluster.RetryTime / puller timeouts","Ensure at least one ordering node of the channel is up and serving blocks","Check remote node logs for FORBIDDEN/SERVICE_UNAVAILABLE responses that would abort retries early"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"for _, ep := range endpoints { if conn, err := grpc.Dial(ep, grpc.WithBlock(), grpc.WithTimeout(2*time.Second)); err != nil { log.Printf(\"endpoint %s unreachable\", ep) } }","typeGuard":"func isRetryExhausted(err error) bool { return errors.Is(err, cluster.ErrRetryCountExhausted) }","tryCatchPattern":"cfgBlock, err := cluster.GetLatestConfigBlock(puller, latestHeight)\nif errors.Is(err, cluster.ErrRetryCountExhausted) {\n    // all endpoints failed; escalate or back off and retry later\n    return err\n}","preventionTips":["Confirm at least one ordering endpoint is reachable before starting pulls","Tune RetryTime / retry budgets above expected recovery windows","Track endpoint health and rotate to live ones","Investigate per-endpoint errors (forbidden/unavailable) that exhaust retries"],"tags":["fabric","orderer","retry","raft"],"backgroundTag":"retry-attempts-exhausted","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}