hyperledger/fabric · error
proposal response was not successful, error code %d, msg %s
Error message
proposal response was not successful, error code %d, msg %s
What it means
CreateSignedTx validates that every proposal response has a successful status code (200-399). If any response reports an error status, the transaction cannot proceed and the error includes the peer's status code and message, which come from chaincode execution or endorser rejection.
Source
Thrown at protoutil/txutils.go:182
signerBytes, err := signer.Serialize()
if err != nil {
return nil, err
}
shdr, err := UnmarshalSignatureHeader(hdr.SignatureHeader)
if err != nil {
return nil, err
}
if !bytes.Equal(signerBytes, shdr.Creator) {
return nil, errors.New("signer must be the same as the one referenced in the header")
}
// ensure that all actions are bitwise equal and that they are successful
var a1 []byte
for n, r := range resps {
if r.Response.Status < 200 || r.Response.Status >= 400 {
return nil, errors.Errorf("proposal response was not successful, error code %d, msg %s", r.Response.Status, r.Response.Message)
}
if n == 0 {
a1 = r.Payload
continue
}
if !bytes.Equal(a1, r.Payload) {
return nil, errors.Errorf("ProposalResponsePayloads do not match (base64): '%s' vs '%s'",
b64.StdEncoding.EncodeToString(r.Payload), b64.StdEncoding.EncodeToString(a1))
}
}
// fill endorsements according to their uniqueness
endorsersUsed := make(map[string]struct{})
var endorsements []*peer.Endorsement
for _, r := range resps {
if r.Endorsement == nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Inspect r.Response.Status and r.Response.Message to find the chaincode/endorsement failure cause
- Fix the chaincode logic or the invoke arguments that caused the failure status
- For MVCC conflicts, retry the transaction or reduce key contention
- Ensure all collected responses are successful and consistent before calling CreateSignedTx
Example fix
// before
env, err := protoutil.CreateSignedTx(proposal, signer, resps...) // one resp has status 500
// after
for _, r := range resps {
if r.Response.Status < 200 || r.Response.Status >= 400 {
return nil, fmt.Errorf("endorsement failed (%d): %s", r.Response.Status, r.Response.Message)
}
}
env, err := protoutil.CreateSignedTx(proposal, signer, resps...) Defensive patterns
Strategy: validation
Validate before calling
func allResponsesSuccessful(resps []*peer.ProposalResponse) error {
for _, r := range resps {
if r.Response.Status < 200 || r.Response.Status >= 400 {
return fmt.Errorf("endorsement %d: %s", r.Response.Status, r.Response.Message)
}
}
return nil
} Type guard
func isSuccess(r *peer.ProposalResponse) bool {
return r != nil && r.Response != nil && r.Response.Status >= 200 && r.Response.Status < 400
} Try / catch
if err := allResponsesSuccessful(resps); err != nil {
// inspect status/message, retry invoke or surface chaincode error
return nil, err
}
tx, err := protoutil.CreateSignedTx(proposal, signer, resps...) Prevention
- Check Response.Status on every endorsement before tx assembly
- Handle MVCC_READ_CONFLICT with retries/backoff
- Fix or wrap chaincode errors so status codes are meaningful
When it happens
Trigger: A chaincode invocation returned an error status (e.g. 500 with 'transaction returned with failure') or an endorser rejected the proposal (e.g. 400 for MVCC conflict, endorsement policy failure), and the caller still tries to assemble a transaction.
Common situations: Chaincode returned an error from Invoke; read-write set conflicts (MVCC_READ_CONFLICT) under concurrency; endorsement policy violations; chaincode container errors/timeout.
Related errors
- failed constructing descriptor for %v
- ProposalResponsePayloads do not match (base64): '%s' vs '%s'
- First message needs to be a register
- TLS is active but chaincode %s didn't send certificate
- Chaincode %s with given certificate hash %v not found in reg
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c58dc1747f0df609.
Report an issue: GitHub.