hyperledger/fabric · error

error marshaling ProposalResponsePayload

Error message

error marshaling ProposalResponsePayload

What it means

After marshaling the ChaincodeAction, GetBytesProposalResponsePayload marshals the enclosing ProposalResponsePayload (extension bytes + proposal hash) and wraps any failure with this message. Like the sibling errors, a real failure indicates a protobuf descriptor/library mismatch rather than business data.

Source

Thrown at protoutil/proputils.go:131

// GetBytesProposalResponsePayload gets proposal response payload
func GetBytesProposalResponsePayload(hash []byte, response *peer.Response, result []byte, event []byte, ccid *peer.ChaincodeID) ([]byte, error) {
	cAct := &peer.ChaincodeAction{
		Events: event, Results: result,
		Response:    response,
		ChaincodeId: ccid,
	}
	cActBytes, err := proto.Marshal(cAct)
	if err != nil {
		return nil, errors.Wrap(err, "error marshaling ChaincodeAction")
	}

	prp := &peer.ProposalResponsePayload{
		Extension:    cActBytes,
		ProposalHash: hash,
	}
	prpBytes, err := proto.Marshal(prp)
	return prpBytes, errors.Wrap(err, "error marshaling ProposalResponsePayload")
}

// GetBytesChaincodeProposalPayload gets the chaincode proposal payload
func GetBytesChaincodeProposalPayload(cpp *peer.ChaincodeProposalPayload) ([]byte, error) {
	if cpp == nil {
		return nil, errors.New("error marshaling ChaincodeProposalPayload: proto: Marshal called with nil")
	}
	cppBytes, err := proto.Marshal(cpp)
	return cppBytes, errors.Wrap(err, "error marshaling ChaincodeProposalPayload")
}

// GetBytesResponse gets the bytes of Response
func GetBytesResponse(res *peer.Response) ([]byte, error) {
	if res == nil {
		return nil, errors.New("error marshaling Response: proto: Marshal called with nil")
	}
	resBytes, err := proto.Marshal(res)
	return resBytes, errors.Wrap(err, "error marshaling Response")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Pin a single fabric-protos-go version and rebuild (`go mod tidy && go build`)
  2. Verify ProposalHash is a normal []byte (any content is marshalable; so inspect proto init)
  3. Rebuild with `go clean -cache` to clear stale descriptors
Defensive patterns

Strategy: validation

Validate before calling

prp := &peer.ProposalResponsePayload{Extension: cActBytes, ProposalHash: hash}
if _, err := proto.Marshal(prp); err != nil {
	return fmt.Errorf("ProposalResponsePayload not marshalable: %w", err)
}

Type guard

func prpMarshalable(prp *peer.ProposalResponsePayload) bool {
	if prp == nil { return false }
	_, err := proto.Marshal(prp)
	return err == nil
}

Try / catch

prpBytes, err := protoutil.GetBytesProposalResponsePayload(hash, result, event, response, ccid)
if err != nil {
	log.Errorf("proposal response payload marshal failed (proto runtime mismatch?): %v", err)
	return err
}

Prevention

When it happens

Trigger: CreateProposalResponse / CreateProposalResponseFailure / TestProposalResponse / ProcessProposalSuccessfullyOrError invoking GetBytesProposalResponsePayload with a hash and previously marshaled extension bytes, where proto.Marshal of the 2-field ProposalResponsePayload fails — practically only from proto incompatibility or corrupted binary.

Common situations: Divergent fabric-protos-go in plugins/external builders; corrupted installs; exotic platforms where the proto registry fails to init.

Related errors


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