hyperledger/fabric · error
nil pRespPayload.Extension
Error message
nil pRespPayload.Extension
What it means
Returned by v20 extractValidationArtifacts when the proposal response payload decodes but its Extension is nil — the chaincode action bytes are missing from the endorsed payload, so validation artifacts cannot be extracted.
Source
Thrown at core/handlers/validation/builtin/v20/validation_logic.go:159
tx, err := protoutil.UnmarshalTransaction(payl.Data)
if err != nil {
logger.Errorf("VSCC error: GetTransaction failed, err %s", err)
return nil, err
}
cap, err := protoutil.UnmarshalChaincodeActionPayload(tx.Actions[actionPosition].Payload)
if err != nil {
logger.Errorf("VSCC error: GetChaincodeActionPayload failed, err %s", err)
return nil, err
}
pRespPayload, err := protoutil.UnmarshalProposalResponsePayload(cap.Action.ProposalResponsePayload)
if err != nil {
err = fmt.Errorf("GetProposalResponsePayload error %s", err)
return nil, err
}
if pRespPayload.Extension == nil {
err = fmt.Errorf("nil pRespPayload.Extension")
return nil, err
}
respPayload, err := protoutil.UnmarshalChaincodeAction(pRespPayload.Extension)
if err != nil {
err = fmt.Errorf("GetChaincodeAction error %s", err)
return nil, err
}
return &validationArtifacts{
rwset: respPayload.Results,
prp: cap.Action.ProposalResponsePayload,
endorsements: cap.Action.Endorsements,
chdr: chdr,
env: env,
payl: payl,
cap: cap,
}, nil
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure complete endorsements with a ChaincodeAction extension
- Reject the incomplete transaction
Example fix
// before
prp := &peer.ProposalResponsePayload{ProposalHash: hash} // Extension missing
// after
prp := &peer.ProposalResponsePayload{
ProposalHash: hash,
Extension: protoutil.MarshalOrPanic(&peer.ChaincodeAction{Results: rwset}),
} Defensive patterns
Strategy: validation
Validate before calling
prp := &peer.ProposalResponsePayload{}
if err := proto.Unmarshal(capBytes, prp); err == nil {
if prp.Extension == nil {
return fmt.Errorf("endorsement missing ChaincodeAction extension")
}
} Type guard
func hasExtension(prp *peer.ProposalResponsePayload) bool {
return prp != nil && prp.Extension != nil
} Try / catch
artifacts, err := extractValidationArtifacts(bytes, policy)
if err != nil {
if strings.Contains(err.Error(), "nil pRespPayload.Extension") {
return nil, validationerrors.TXMalformed
}
return nil, err
} Prevention
- Always populate ProposalResponsePayload.Extension when building endorsements
- Prefer SDK endorsement flows over manual proto assembly
- Test custom endorser code against the standard validation path
- Log the txID when rejecting to trace the offending client
When it happens
Trigger: A ProposalResponsePayload was constructed without populating Extension (e.g. an endorsement built by custom code that only set ProposalHash), or Extension was explicitly nil in the serialized bytes.
Common situations: Custom SDK or hand-rolled endorsement code omitting the ChaincodeAction extension; truncated/zeroed transaction data from a bad write path; crafted malicious transactions.
Related errors
- implicit policy evaluation failed - %d sub-policies were sat
- proposal hash does not match
- could not serialize the signing identity
- could not sign the proposal response payload
- VSCC error: invocation of lscc(%s) does not have appropriate
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/8ffb2e6af0d9ad72.
Report an issue: GitHub.