hyperledger/fabric · warning · ErrServiceUnavailable
service unavailable
Error message
service unavailable
What it means
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.
Source
Thrown at orderer/common/cluster/deliver.go:638
// while a timeout expires, so ensure it's only called once.
cancelFunc: func() {
once.Do(cancel)
},
AtomicBroadcast_DeliverClient: stream,
}, nil
}
}
type errorAndResponse struct {
err error
resp *orderer.DeliverResponse
}
// ErrForbidden denotes that an ordering node refuses sending blocks due to access control.
var ErrForbidden = errors.New("forbidden pulling the channel")
// ErrServiceUnavailable denotes that an ordering node is not servicing at the moment.
var ErrServiceUnavailable = errors.New("service unavailable")
// ErrNotInChannel denotes that an ordering node is not in the channel
var ErrNotInChannel = errors.New("not in the channel")
var ErrRetryCountExhausted = errors.New("retry attempts exhausted")
View on GitHub (pinned to 2736b63f8f)
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
Defensive patterns
Strategy: retry
Validate before calling
if err := puller.TestChainParticipant(); errors.Is(err, cluster.ErrServiceUnavailable) { log.Println("cluster temporarily unavailable; will retry") } Type guard
func isUnavailable(err error) bool { return errors.Is(err, cluster.ErrServiceUnavailable) } Try / catch
err := puller.PullBlock(seq)
if errors.Is(err, cluster.ErrServiceUnavailable) {
time.Sleep(backoff)
return retryPull(seq)
} Prevention
- 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
When it happens
Trigger: extractBlockFromResponse receives common.Status_SERVICE_UNAVAILABLE; probeEndpoints confirms all endpoints returned only unavailable errors and none healthy (deliver.go:359).
Common situations: 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.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- retry attempts exhausted
- cannot enable channel capabilities without orderer support f
- Must set some OrdererAddresses
- failed computing orderer addresses
- orderer is required, but no ordering endpoint or endorser cl
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/e9e8431579c02c74.
Report an issue: GitHub.