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

  1. Wait and retry — this is usually transient while nodes finish starting or catch up
  2. Check the remote orderer logs/health to see why it is not servicing the channel (e.g. chain still starting)
  3. Ensure the node has joined the channel and the ledger is initialized
  4. 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

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

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/e9e8431579c02c74. Report an issue: GitHub.