hyperledger/fabric · error

proposal failed with status: %d - %s

Error message

proposal failed with status: %d - %s

What it means

Commit requires the endorser proposal to have succeeded (Status == Status_SUCCESS, 200). If any (first) response reports a non-success status, the transaction is not assembled and the status plus message are surfaced to the user.

Source

Thrown at internal/peer/lifecycle/chaincode/commit.go:200

	if len(responses) == 0 {
		// this should only be empty due to a programming bug
		return errors.New("no proposal responses received")
	}

	// all responses will be checked when the signed transaction is created.
	// for now, just set this so we check the first response's status
	proposalResponse := responses[0]

	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)
	}
	// assemble a signed transaction (it's an Envelope message)
	env, err := protoutil.CreateSignedTx(proposal, c.Signer, responses...)
	if err != nil {
		return errors.WithMessage(err, "failed to create signed transaction")
	}

	var dg *chaincode.DeliverGroup
	var ctx context.Context
	if c.Input.WaitForEvent {
		var cancelFunc context.CancelFunc
		ctx, cancelFunc = context.WithTimeout(context.Background(), c.Input.WaitForEventTimeout)
		defer cancelFunc()

		dg = chaincode.NewDeliverGroup(
			c.DeliverClients,
			c.Input.PeerAddresses,
			c.Signer,

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the message in the error for the concrete rejection cause (e.g. 'attempted to define committed sequence X with lower number' or endorsement policy failure).
  2. Ensure all required orgs ran approveformyorg and that each endorser's committed/approved definitions match (--sequence, -v).
  3. Confirm chaincode is installed (peer lifecycle chaincode queryinstalled) on all endorsing peers.
  4. Check peer logs on the failing endorser for the exact chaincode error and re-run after fixing.

Example fix

// before
peer lifecycle chaincode commit ... --sequence 2   // when approved sequence is 1
// after
peer lifecycle chaincode queryapproved -C mychannel -n mycc   # check sequence
peer lifecycle chaincode commit ... --sequence 1
Defensive patterns

Strategy: try-catch

Validate before calling

if resp.Response.Status != int32(cb.Status_SUCCESS) {
    // inspect resp.Response.Message before assembling the tx
    log.Printf("endorsement rejected: %d %s", resp.Response.Status, resp.Response.Message)
}

Try / catch

if err := commit(...); err != nil {
    var statusErr interface{ Status() int32 }
    if strings.Contains(err.Error(), "proposal failed with status") {
        // parse message: check sequence/version mismatch, endorsement policy, txid conflicts
    }
}

Prevention

When it happens

Trigger: An endorser rejected the commit proposal — e.g. endorsement policy failures, chaincode definition mismatch (sequence/version mismatch vs approved definition), MVCC/txid conflicts, or a chaincode-level error message in proposalResponse.Response.Message.

Common situations: Committing a definition whose sequence/version differs from the approved one; not enough orgs endorsing to satisfy the policy; chaincode not installed on the endorsing peer; transient txid collision (`the txid ... already exists`).

Related errors


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