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

  1. Inspect the latest channel config block to see if the node's certificates are still consenter members
  2. 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
  3. Re-add the node's certificate to the channel via a config update if membership is intended
  4. 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

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

Related errors


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