hyperledger/fabric · critical

access denied: channel

Error message

access denied: channel [%s] creator org unknown, creator is malformed

What it means

The endorser could not deserialize the creator bytes in the SignatureHeader into a valid MSP identity. This is the deliberately opaque 'access denied' returned when the serialized identity is malformed (as opposed to valid-but-unauthorized, which yields the generic creator-org message). The actual deserialization error is only logged server-side.

Solutions

  1. Verify the org's MSP definition (with the client's CA cert) is included in the channel configuration for the target channel.
  2. Ensure SignatureHeader.Creator is a marshaled mspprotos.SerializedIdentity{Mspid, IdBytes} with a valid PEM x509 certificate.
  3. Check peer logs (the 'access denied' Warnw entry) for the underlying deserialization error and fix the certificate format/MSP ID accordingly.
  4. Regenerate client certs from the correct org CA and confirm mspId matches the organization name in configtx.

Example fix

// before
creator := certPEM // raw PEM, not a SerializedIdentity
// after
creator, _ := proto.Marshal(&mspprotos.SerializedIdentity{Mspid: "Org1MSP", IdBytes: certPEM})
Defensive patterns

Strategy: try-catch

Validate before calling

var sid mspprotos.SerializedIdentity
if err := proto.Unmarshal(shdr.Creator, &sid); err != nil {
    return fmt.Errorf("creator is not a SerializedIdentity: %w", err)
}
if _, err := x509.ParseCertificate(certDER); err != nil {
    return fmt.Errorf("creator cert unparseable: %w", err)
}

Type guard

func isWellFormedIdentity(creator []byte) bool {
    var sid mspprotos.SerializedIdentity
    return proto.Unmarshal(creator, &sid) == nil && len(sid.Mspid) > 0 && len(sid.IdBytes) > 0
}

Try / catch

// client side
catch (err) {
  if (String(err).includes('creator org unknown, creator is malformed')) {
    // inspect peer logs, verify MSP config + cert format, then rebuild identity
    await reloadWalletIdentity();
  }
  throw err;
}

Prevention

When it happens

Trigger: ProcessProposal -> preProcess -> Validate when idDeserializer.DeserializeIdentity(SignatureHeader.Creator) fails — creator bytes are not a valid mspprotos.SerializedIdentity, reference an MSP unknown to the peer, or contain an unparseable x509 cert.

Common situations: Client's MSP ID not present in the peer/channel configuration, corrupted or wrong-format certificate PEM, using an identity from a different network, Fabric version mismatch in identity protobuf serialization, peer missing the org's MSP config (update channel config).

Understand the failure class

Related errors


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

Appendix: source

Thrown at core/endorser/msgvalidation.go:173

	expectedTxID := protoutil.ComputeTxID(up.SignatureHeader.Nonce, up.SignatureHeader.Creator)
	if up.TxID() != expectedTxID {
		return errors.Errorf("incorrectly computed txid '%s' -- expected '%s'", up.TxID(), expectedTxID)
	}

	if up.SignedProposal.ProposalBytes == nil {
		return errors.Errorf("empty proposal bytes")
	}

	if up.SignedProposal.Signature == nil {
		return errors.Errorf("empty signature bytes")
	}

	// get the identity of the creator
	creator, err := idDeserializer.DeserializeIdentity(up.SignatureHeader.Creator)
	if err != nil {
		logger.Warnw("access denied", "error", err, "identity", protoutil.LogMessageForSerializedIdentity(up.SignatureHeader.Creator))
		return errors.Errorf("access denied: channel [%s] creator org unknown, creator is malformed", up.ChannelID())
	}

	genericAuthError := errors.Errorf("access denied: channel [%s] creator org [%s]", up.ChannelID(), creator.GetMSPIdentifier())
	// ensure that creator is a valid certificate
	err = creator.Validate()
	if err != nil {
		logger.Warnw("access denied: identity is not valid", "error", err, "identity", protoutil.LogMessageForSerializedIdentity(up.SignatureHeader.Creator))
		return genericAuthError
	}

	logger = logger.With("mspID", creator.GetMSPIdentifier())

	logger.Debug("creator is valid")

	// validate the signature
	err = creator.Verify(up.SignedProposal.ProposalBytes, up.SignedProposal.Signature)
	if err != nil {
		logger.Warnw("access denied: creator's signature over the proposal is not valid", "error", err, "identity", protoutil.LogMessageForSerializedIdentity(up.SignatureHeader.Creator))

View on GitHub (pinned to 2736b63f8f)