How do I fix Hyperledger Fabric ENDORSEMENT_POLICY_FAILURE? · Jumpstart Blockchain
How do I fix Hyperledger Fabric ENDORSEMENT_POLICY_FAILURE?
The endorsements attached to the transaction don't satisfy the chaincode policy at validation. Check the real policy (often MAJORITY by default), endorse from every required org, and verify roles.
Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE)
On the peer, the matching log line looks something like:
validation of endorsement policy for chaincode basic in tx 12:0 failed: signature set did not satisfy policy
The frustrating part is that the chaincode ran fine. The endorsing peer executed it, signed the result, and the client even got a success response. The transaction was rejected later, at validation, because the set of signatures attached to it didn't satisfy the chaincode's endorsement policy.
Where endorsement fits in the flow
Fabric uses execute-order-validate:
Execute. The client sends a proposal to one or more endorsing peers. Each simulates the chaincode and signs the resulting read/write set.
Order. The client bundles the endorsements into a transaction and sends it to the ordering service.
Validate. Every peer checks each transaction in the block against the endorsement policy and for read conflicts. Invalid transactions stay in the block, marked with a status code, and their writes are not applied.
ENDORSEMENT_POLICY_FAILURE is decided in step 3. That's why the client-side success from step 1 means nothing on its own.
This prints Chaincode invoke successful. result: status:200. That only means the Org1 peer endorsed it. If the policy needs Org1 and Org2, the transaction is invalidated at commit and the CLI never tells you, unless you add --waitForEvent. Always use --waitForEvent when testing, and pass one --peerAddresses/ pair per organization the policy requires:
Mindtree has partnered with Hyperledger which the company said will help Mindtree to accelerate the development of its capabilities around Hyperledger.
The chaincode endorsement policy is part of the chaincode definition, set when orgs approved and committed it:
--signature-policy "AND('Org1MSP.peer','Org2MSP.peer')" sets an explicit policy.
--channel-config-policy points to a policy in the channel config.
Neither means the default, /Channel/Application/Endorsement, which in the standard configtx.yaml is MAJORITY Endorsement: a majority of the channel's application orgs must endorse.
That default surprises people. With two orgs, a majority is both. With three, it's two of three. Adding an org to the channel can change what "majority" means and start failing transactions that used to pass.
The policy is in validation_parameter (encoded). If you're unsure what was used, look at the scripts or pipeline that ran approveformyorg.
Common causes
1. Not enough organizations endorsed. You targeted one peer, or your client's peer selection didn't pick peers from every required org. With the Fabric Gateway (Fabric 2.4+ and the fabric-gateway client libraries), the gateway peer uses service discovery to pick endorsers for you. Discovery only finds other orgs' peers if anchor peers are configured for each org on the channel. No anchor peers, no cross-org endorsement.
2. The role in the policy doesn't match the signer.'Org1MSP.peer' only matches identities classified as peer. That classification comes from Node OUs in the MSP's config.yaml. If Node OUs aren't enabled for that MSP, or the peer's certificate wasn't issued with the peer OU, its signature won't satisfy .peer. Either fix the MSP/certificates or use .member, which matches any valid identity from that org.
3. Private data collection policies. A collection can define its own endorsementPolicy in the collection config. Writes to that collection must satisfy the collection policy, not the chaincode-level one.
4. Key-level (state-based) endorsement. If chaincode calls SetStateValidationParameter on a key, any transaction that writes that key must satisfy that key's policy. The gateway can't always predict these, so name the orgs explicitly:
In Go, the equivalent is client.WithEndorsingOrganizations("Org1MSP", "Org2MSP").
5. Certificate or MSP problems. A peer whose certificate has expired, was revoked, or was issued by a CA that the channel config doesn't list for that MSP produces a signature that doesn't count.
A related failure: endorsements that don't match
If the endorsing peers return different results, the client can't assemble a valid transaction. The gateway reports that the endorsement responses don't match instead of submitting. The cause is non-deterministic chaincode: reading the system clock, random numbers, iterating a Go map, or calling an external API. Every endorser must produce the identical read/write set from the same input. Pass timestamps and IDs in as arguments, or use GetTxTimestamp().
Get the peer to tell you why
Turn up policy logging on a peer that's rejecting transactions:
You can also change it at runtime through the peer's operations service (PUT /logspec). The debug output shows which principals were evaluated and which signatures failed to match, which usually points straight at cause 1, 2 or 5.
Changing the policy
A policy change is a chaincode definition upgrade: approve with the next sequence number by enough orgs to satisfy the channel's LifecycleEndorsement policy, then commit.
Every org must approve the same definition (including the same policy) or the commit fails. Loosening a policy is a governance decision, not a debugging shortcut: an OR policy means any single org can write state on its own.
Checklist
Confirm validation status: --waitForEvent on the CLI, or the commit status in the Gateway SDK.
Work out the real policy: explicit, channel-config, or the MAJORITY Endorsement default.
Make sure a peer from every required org endorses: anchor peers and discovery for the Gateway, explicit --peerAddresses for the CLI.
Check Node OUs and certificates if the policy uses .peer or .admin roles.
Account for collection-level and key-level policies.
Enable policies/cauthdsl debug logging on a validating peer to see which signature failed.
Recently, Hyperledger part of the Linux Foundation launched the latest version of enterprise blockchain Hyperledger Fabric - v1.4 LTS. This is Fabric’s first Long-Term-Support release.