hyperledger/fabric · error · ErrForbidden
forbidden pulling the channel
Error message
forbidden pulling the channel
What it means
ErrForbidden is a sentinel error returned when an ordering node refuses to send blocks due to access control — the Deliver RPC is authorized but the caller is not permitted to pull this channel. During endpoint probing, if every endpoint yields forbidden, the error is surfaced as the probe result so callers (like eviction detection) know the node was denied channel access.
Source
Thrown at orderer/common/cluster/deliver.go:635
Certificate: cert,
waitTimeout: waitTimeout,
// The stream might be canceled while Close() is being called, but also
// 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
- Inspect the latest channel config block to see if the node's certificates are still consenter members
- If the node was evicted, follow the eviction-suspection flow: pull the latest config block from another endpoint or genesis and rejoin the channel if intended
- Re-add the node's certificate to the channel via a config update if membership is intended
- Verify the correct channel name and TLS root CAs are used when creating the BlockPuller
Defensive patterns
Strategy: type-guard
Validate before calling
err := puller.TestChainParticipant()
if errors.Is(err, cluster.ErrForbidden) { return fmt.Errorf("node lacks channel access; check consenter certs") } Type guard
func isForbidden(err error) bool { return errors.Is(err, cluster.ErrForbidden) } Try / catch
err := puller.PullBlock(seq)
if errors.Is(err, cluster.ErrForbidden) {
// node evicted or certs revoked: fetch latest config block via another endpoint
return handleEviction()
} Prevention
- Verify node certificates are present in the channel config before starting services
- Use the eviction suspicion flow to detect self-removal early
- Keep channel membership and local node certs in sync after updates
- Confirm channel name and TLS root CAs are correct
When it happens
Trigger: extractBlockFromResponse receives common.Status_FORBIDDEN; probeEndpoints/TestChainParticipant sees only FORBIDDEN errors from all endpoints and no healthy ones (deliver.go:362).
Common situations: A node's TLS certificate or ordering identity was removed/revoked from the channel (eviction scenario); channel membership changed via config update and the local node's certs no longer appear; pointing a node at a channel it never joined.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- session binding read failed
- session binding mismatch
- invalid certificate DER
- failed to create new stream
- failed generating TLS Binding material
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/5c6dc1fe88ae1109.
Report an issue: GitHub.