hyperledger/fabric · error
access denied: channel [%s] creator org [%s]
Error message
access denied: channel [%s] creator org [%s]
What it means
The endorser could not authenticate the transaction's creator. After deserializing the identity from the proposal's SignatureHeader, creator.Validate() fails (expired/revoked certificate, unknown MSP, malformed cert), so the endorser rejects the proposal with this generic authorization error naming the channel and the MSP ID derived from the creator identity.
Source
Thrown at core/endorser/msgvalidation.go:176
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))
return genericAuthError
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate or renew the client's signing certificate/keystore (e.g. re-enroll with fabric-ca) and update the SDK wallet
- Verify the peer's MSP configuration contains the CA that issued the creator identity (core.yaml peer.mspConfigPath / channel MSP)
- Confirm the org's MSP is defined in the channel config and the client signs with an identity from that MSP
- Check peer logs for the preceding 'access denied: identity is not valid' warning with the underlying x509 error to pinpoint cert validity issues
Example fix
// before: stale cert in connection profile
const gateway = await connect({ identity: await wallet.get('expiredUser'), ... });
// after: re-enroll and store fresh identity
const enrollment = await ca.registerAndEnroll({ enrollmentID: 'user1', affiliation: 'org1.department1' });
await wallet.put('user1', new X509WalletIdentity({ mspId: 'Org1MSP', cert: enrollment.certificate, key: enrollment.key })); Defensive patterns
Strategy: validation
Validate before calling
const cert = new crypto.X509Certificate(identityCertPem);
if (cert.validityDateEnd < new Date()) throw new Error('client cert expired; re-enroll before submitting');
// also confirm the issuing CA cert exists in the peer org's MSP folder
Type guard
function hasValidIdentity(walletIdentity) {
return Boolean(walletIdentity && walletIdentity.mspId && walletIdentity.credentials?.certificate && walletIdentity.credentials?.privateKey);
} Try / catch
try {
await contract.submitTransaction('fn', 'arg');
} catch (e) {
if (/access denied: channel \[.*\] creator org/.test(e.message)) {
await reEnrollAndReplaceWalletIdentity(); // invalid/expired creator cert
}
throw e;
} Prevention
- Monitor certificate expiry and re-enroll clients before expiration
- Keep peer/channel MSP configs in sync with the CA that issues client certs
- After regenerating network crypto material, always refresh SDK wallets
- Pin identities per environment; never reuse wallets across networks
When it happens
Trigger: ProcessProposal -> preProcess -> Validate where idDeserializer.DeserializeIdentity succeeds but creator.Validate() returns an error, e.g. the client's signing certificate has expired, was revoked, is not issued by an MSP known to the peer, or the serialized identity bytes are corrupt.
Common situations: Client SDK using an expired or rotated enrollment cert; peer's MSP config (mspConfigPath) missing the org's CA cert; cryptogen/fabric-ca certs regenerated after peer joined channel; copying wallets between environments; clock skew making a valid cert appear invalid.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- empty signature bytes
- access denied: channel [%s] creator org unknown, creator is
- failed deserializing signed data identity during channelless
- could not decode the PEM structure
- parseCertificate failed
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/226b0850fe6de8bf.
Report an issue: GitHub.