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

  1. Ensure complete endorsements with a ChaincodeAction extension
  2. 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

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


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