hyperledger/fabric · error

failed to unmarshal proposal response's response payload

Error message

failed to unmarshal proposal response's response payload

What it means

In writePackage(), the payload of a successful proposal response could not be proto-unmarshaled into lb.GetInstalledChaincodePackageResult. It means the peer returned success status but its payload bytes are not the expected protobuf message — typically an incompatible peer version or a corrupted response.

Source

Thrown at internal/peer/lifecycle/chaincode/getinstalledpackage.go:153

		return errors.New("received nil proposal response")
	}

	if proposalResponse.Response == nil {
		return errors.New("received proposal response with nil response")
	}

	if proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {
		return errors.Errorf("proposal failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
	}

	return i.writePackage(proposalResponse)
}

func (i *InstalledPackageGetter) writePackage(proposalResponse *pb.ProposalResponse) error {
	result := &lb.GetInstalledChaincodePackageResult{}
	err := proto.Unmarshal(proposalResponse.Response.Payload, result)
	if err != nil {
		return errors.Wrap(err, "failed to unmarshal proposal response's response payload")
	}

	outputFile := filepath.Join(i.Input.OutputDirectory, i.Input.PackageID+".tar.gz")

	dir, name := filepath.Split(outputFile)
	// translate dir into absolute path
	if dir, err = filepath.Abs(dir); err != nil {
		return err
	}

	err = i.Writer.WriteFile(dir, name, result.ChaincodeInstallPackage)
	if err != nil {
		err = errors.Wrapf(err, "failed to write chaincode package to %s", outputFile)
		logger.Error(err.Error())
		return err
	}

	return nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Match the peer CLI binary version to the Fabric peer version it connects to.
  2. Re-run the command to rule out a transient/corrupted response.
  3. Check for intermediaries (proxies, service meshes) altering gRPC response bodies.
  4. Inspect peer logs to confirm what the peer actually serialized.

Example fix

// before: v2.2 peer CLI against v2.5 peer
./peer-2.2 lifecycle chaincode getinstalledpackage ...
// after: aligned versions
./peer-2.5 lifecycle chaincode getinstalledpackage ...
Defensive patterns

Strategy: try-catch

Validate before calling

if len(proposalResponse.Response.Payload) == 0 {
    return errors.New("empty proposal response payload")
}

Type guard

func isPkgResult(b []byte) (*lb.GetInstalledChaincodePackageResult, bool) {
    r := &lb.GetInstalledChaincodePackageResult{}
    if proto.Unmarshal(b, r) != nil { return nil, false }
    return r, true
}

Try / catch

if err := writePackage(resp); err != nil {
    if strings.Contains(err.Error(), "failed to unmarshal") {
        // upgrade/realign CLI version and retry
    }
    return err
}

Prevention

When it happens

Trigger: proto.Unmarshal(proposalResponse.Response.Payload, result) returns an error after Get() received a SUCCESS-status response; the payload was produced by a peer whose _lifecycle result schema differs from the client's protos.

Common situations: Client binaries (peer CLI) are a different Fabric version than the peer node; a proxy/middleware mangled or truncated the response payload; custom peer builds returning non-standard payloads.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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