{"record":{"id":"e9e8431579c02c74","repo":"hyperledger/fabric","slug":"service-unavailable","errorCode":null,"errorMessage":"service unavailable","messagePattern":"service unavailable","errorType":"exception","errorClass":"ErrServiceUnavailable","httpStatus":null,"severity":"warning","filePath":"orderer/common/cluster/deliver.go","lineNumber":638,"sourceCode":"\t\t\t// while a timeout expires, so ensure it's only called once.\n\t\t\tcancelFunc: func() {\n\t\t\t\tonce.Do(cancel)\n\t\t\t},\n\t\t\tAtomicBroadcast_DeliverClient: stream,\n\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":620,"sourceCodeEnd":644,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/deliver.go#L620-L644","documentation":"ErrServiceUnavailable is a sentinel indicating an ordering node is not servicing the channel at the moment — it returned Status_SERVICE_UNAVAILABLE on a Deliver request. When all probed endpoints report unavailable, the error is propagated so the caller knows the whole cluster is temporarily unable to serve blocks.","triggerScenarios":"extractBlockFromResponse receives common.Status_SERVICE_UNAVAILABLE; probeEndpoints confirms all endpoints returned only unavailable errors and none healthy (deliver.go:359).","commonSituations":"Ordering nodes are booting up and not yet serving the channel; the serviceability check (chain not yet started or halted); node overloaded or crashed mid-consensus; entire cluster down during startup or maintenance.","solutions":["Wait and retry — this is usually transient while nodes finish starting or catch up","Check the remote orderer logs/health to see why it is not servicing the channel (e.g. chain still starting)","Ensure the node has joined the channel and the ledger is initialized","Restart the affected ordering nodes if the serviceable state is stuck"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := puller.TestChainParticipant(); errors.Is(err, cluster.ErrServiceUnavailable) { log.Println(\"cluster temporarily unavailable; will retry\") }","typeGuard":"func isUnavailable(err error) bool { return errors.Is(err, cluster.ErrServiceUnavailable) }","tryCatchPattern":"err := puller.PullBlock(seq)\nif errors.Is(err, cluster.ErrServiceUnavailable) {\n    time.Sleep(backoff)\n    return retryPull(seq)\n}","preventionTips":["Use exponential backoff — unavailability is usually transient","Monitor node startup/health endpoints","Ensure nodes have joined the channel before serving","Alert on sustained SERVICE_UNAVAILABLE from all endpoints"],"tags":["fabric","orderer","availability","retry"],"backgroundTag":"service-unavailable","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"}