hyperledger/fabric · error

permission denied

Error message

permission denied

What it means

ErrPermissionDenied is a sentinel error returned when a transaction fails the channel's write-set / message policy evaluation — the submitting principal is not authorized. broadcast.ClassifyError maps it to FORBIDDEN, and ProcessConfigMsg/Apply surface it whenever the signature set does not satisfy the required config policy.

Source

Thrown at orderer/common/msgprocessor/msgprocessor.go:32

	"github.com/hyperledger/fabric-lib-go/common/flogging"
	cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
)

const (
	// These should eventually be derived from the channel support once enabled
	msgVersion = int32(0)
	epoch      = 0
)

var logger = flogging.MustGetLogger("orderer.common.msgprocessor")

// ErrChannelDoesNotExist is returned by the system channel for transactions which
// are not for the system channel ID and are not attempting to create a new channel
var ErrChannelDoesNotExist = errors.New("channel does not exist")

// ErrPermissionDenied is returned by errors which are caused by transactions
// which are not permitted due to an authorization failure.
var ErrPermissionDenied = errors.New("permission denied")

// ErrMaintenanceMode is returned when transactions are rejected because the orderer is in "maintenance mode",
// as defined by ConsensusType.State != NORMAL. This typically happens during consensus-type migration.
var ErrMaintenanceMode = errors.New("maintenance mode")

// Classification represents the possible message types for the system.
type Classification int

const (
	// NormalMsg is the class of standard (endorser or otherwise non-config) messages.
	// Messages of this type should be processed by ProcessNormalMsg.
	NormalMsg Classification = iota

	// ConfigUpdateMsg indicates messages of type CONFIG_UPDATE.
	// Messages of this type should be processed by ProcessConfigUpdateMsg.
	ConfigUpdateMsg

	// ConfigMsg indicates message of type CONFIG.

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Submit the transaction with an identity whose organization satisfies the channel Writers (or config update admins) policy.
  2. Collect the required policy signatures (e.g. majority of orderer org admins) for config updates before broadcasting.
  3. Check that the submitting peer's MSP certificates are current and correctly enrolled.

Example fix

// before
env := signWith(clientOrgIdentity, payload) // org lacks write rights
// after
env := signWith(ordererAdminIdentity, payload)
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure principal satisfies Writers policy before submit
if !channelWriterPolicy.Evaluate([]*msp.Identity{submitter}) {
    return errors.New("submitter does not satisfy channel Writers policy")
}

Try / catch

err := broadcastClient.Send(env)
if errors.Cause(err) == statusError(cb.Status_FORBIDDEN) {
    // authorization failure: fix identity/signatures, do not retry blindly
}

Prevention

When it happens

Trigger: Broadcasting a config or normal message whose creator MSP / signature set fails the channel Writers policy or the applicable config update policy (e.g. Orderer group admins policy during maintenance-mode updates).

Common situations: Using an identity from an org lacking write rights; missing or stale signatures on config update envelopes; MSP certificates expired or from the wrong organization.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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