hyperledger/fabric · error

proposal failed with status: %d - %s

Error message

proposal failed with status: %d - %s

What it means

GetInstalledChaincodePackage's Get() received an endorsed proposal response whose embedded Response status was not cb.Status_SUCCESS. The peer rejected or failed the _lifecycle query, and it surfaces the peer's status code and message. This is the CLI reporting a server-side failure, not a client bug.

Source

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

	if err != nil {
		return errors.WithMessage(err, "failed to create signed proposal")
	}

	proposalResponse, err := i.EndorserClient.ProcessProposal(context.Background(), signedProposal)
	if err != nil {
		return errors.WithMessage(err, "failed to endorse proposal")
	}

	if proposalResponse == nil {
		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

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the peer's status/message in the error to identify the server-side cause (e.g. NOT_FOUND means the package ID isn't installed on that peer).
  2. Run `peer lifecycle chaincode queryinstalled` on the same peer to get the correct PackageID.
  3. Verify --peerAddresses points to a peer in your org where the package was actually installed.
  4. Check the peer container logs for the underlying _lifecycle error.

Example fix

// before: guessing package ID
peer lifecycle chaincode getinstalledpackage --package-id cc_1:abc123
// after: query first, then fetch
peer lifecycle chaincode queryinstalled
peer lifecycle chaincode getinstalledpackage --package-id cc_1:<valid-package-id-from-query>
Defensive patterns

Strategy: validation

Validate before calling

pid, err := queryInstalledPackageID(peerConn, packageLabel)
if err != nil { return err }
// only call getinstalledpackage with a PackageID known to exist on that peer
return getInstalledPackage(peerConn, pid)

Type guard

func hasResponse(r *pb.ProposalResponse) bool { return r != nil && r.Response != nil }

Try / catch

res, err := getter.Get()
if err != nil {
    if strings.Contains(err.Error(), "proposal failed with status") {
        // parse status/message, e.g. fall back to queryinstalled
    }
    return err
}

Prevention

When it happens

Trigger: Running `peer lifecycle chaincode getinstalledpackage` where the peer's endorsement of the GetInstalledChaincodePackage query returns a non-200 Response.Status (e.g. the PackageID does not exist on the peer, or the caller lacks permission).

Common situations: Querying a package ID that was never installed on the targeted peer; typos in the --package-id flag; targeting a peer in another org that has not installed the chaincode; peer returning 500 due to _lifecycle internal errors.

Related errors


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