hyperledger/fabric · error · VSCCEndorsementPolicyError

VSCC error: endorsement policy failure, err: %s

Error message

VSCC error: endorsement policy failure, err: %s

What it means

The endorsement policy evaluation against the transaction's signature set failed, so VSCC rejects the transaction and marks it invalid via policyErr. This is the generic failure branch when there are no duplicated identities — the signatures present simply do not satisfy the chaincode's endorsement policy.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:165

	if err != nil {
		logger.Errorf("VSCC error: GetChaincodeActionPayload failed, err %s", err)
		return policyErr(err)
	}

	signatureSet, err := vscc.deduplicateIdentity(cap)
	if err != nil {
		return policyErr(err)
	}

	// evaluate the signature set against the policy
	err = vscc.policyEvaluator.Evaluate(policyBytes, signatureSet)
	if err != nil {
		logger.Warningf("Endorsement policy failure for transaction txid=%s, err: %s", chdr.GetTxId(), err.Error())
		if len(signatureSet) < len(cap.Action.Endorsements) {
			// Warning: duplicated identities exist, endorsement failure might be cause by this reason
			return policyErr(errors.New(DUPLICATED_IDENTITY_ERROR))
		}
		return policyErr(fmt.Errorf("VSCC error: endorsement policy failure, err: %s", err))
	}

	// do some extra validation that is specific to lscc
	if namespace == "lscc" {
		logger.Debugf("VSCC info: doing special validation for LSCC")
		err := vscc.ValidateLSCCInvocation(chdr.ChannelId, env, cap, payl, vscc.capabilities)
		if err != nil {
			logger.Errorf("VSCC error: ValidateLSCCInvocation failed, err %s", err)
			return err
		}
	}

	return nil
}

// checkInstantiationPolicy evaluates an instantiation policy against a signed proposal.
func (vscc *Validator) checkInstantiationPolicy(chainName string, env *common.Envelope, instantiationPolicy []byte, payl *common.Payload) commonerrors.TxValidationError {
	// get the signature header

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Collect endorsements from the exact set of organizations required by the endorsement policy (peer chaincode invoke normally does this automatically)
  2. Verify endorsing peers' certificates are valid and current (MSP, expiry, rotation)
  3. Check the chaincode's endorsement policy definition (e.g. AND('Org1.member','Org2.member')) matches what clients can satisfy
  4. Inspect the wrapped err in the message (VSCC error: endorsement policy failure, err: ...) for the precise evaluation failure cause

Example fix

// before
// invoking with endorsements from Org1 only, policy requires Org1 AND Org2
proposalTargets = [peerOrg1]
// after
proposalTargets = [peerOrg1Peers, peerOrg2Peers] // collect endorsements from all required orgs
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: verify collected endorsements satisfy the policy before submit
if len(collectedEndorsements) < requiredDistinctOrgs(policy) {
    return errors.New("insufficient endorsements for policy, aborting submit")
}

Try / catch

evt, err := notifier() // commit event
if err != nil { return err }
if code := evt.ValidationCode; code != int32(pb.TxValidationCode_VALID) {
    return fmt.Errorf("tx %s rejected: endorsement policy failure (%v)", evt.TxId, err)
}

Prevention

When it happens

Trigger: Submitting a transaction endorsed by fewer/different organizations than the endorsement policy requires; a signature that does not verify against the claimed creator identity; a mismatch between the policy referenced in the chaincode data and the channel policy actually evaluated.

Common situations: Chaincode endorsement policies changed after the client code was written; requests collected from peers that are not in the policy's member list; expired or rotated certificates invalidating a signature; load-testing tools that fake endorsements.

Related errors


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