hyperledger/fabric · error
transaction returned with failure: %s
Error message
transaction returned with failure: %s
What it means
When the chaincode message type is ChaincodeMessage_ERROR, processChaincodeExecutionResult converts it into this Go error whose text contains the raw payload from the chaincode. It means the chaincode itself reported the transaction failed (e.g. shim.Error was called or the chaincode panicked) — this is not a peer infrastructure failure. The payload bytes are interpolated directly into the message.
Source
Thrown at core/chaincode/chaincode_support.go:196
return nil, nil, errors.Errorf("nil response from transaction %s", txid)
}
if resp.ChaincodeEvent != nil {
resp.ChaincodeEvent.ChaincodeId = ccName
resp.ChaincodeEvent.TxId = txid
}
switch resp.Type {
case pb.ChaincodeMessage_COMPLETED:
res := &pb.Response{}
err := proto.Unmarshal(resp.Payload, res)
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to unmarshal response for transaction %s", txid)
}
return res, resp.ChaincodeEvent, nil
case pb.ChaincodeMessage_ERROR:
return nil, resp.ChaincodeEvent, errors.Errorf("transaction returned with failure: %s", resp.Payload)
default:
return nil, nil, errors.Errorf("unexpected response type %d for transaction %s", resp.Type, txid)
}
}
// Invoke will invoke chaincode and return the message containing the response.
// The chaincode will be launched if it is not already running.
func (cs *ChaincodeSupport) Invoke(txParams *ccprovider.TransactionParams, chaincodeName string, input *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
ccid, cctype, err := cs.CheckInvocation(txParams, chaincodeName, input)
if err != nil {
return nil, errors.WithMessage(err, "invalid invocation")
}
h, err := cs.Launch(ccid)
if err != nil {
return nil, err
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Read the payload text embedded in the error — it comes from the chaincode's shim.Error message and pinpoints the failure.
- Fix the application/chaincode logic that generated the error (invalid arguments, missing state, permission checks).
- If it's a panic, check chaincode container logs for a stack trace and add recovery/argument validation.
- Verify the client sends the expected arguments (correct number, types, JSON shape) for the invoked function.
Example fix
// before: chaincode panics on missing arg
args := stub.GetStringArgs()
key := args[1] // panic -> ERROR message
// after: validate and return a clean error
if len(args) < 2 {
return shim.Error("expected key argument")
}
key := args[1] Defensive patterns
Strategy: try-catch
Validate before calling
// validate arguments before invoking to avoid chaincode-level rejections
if len(args) == 0 || args[0] == "" {
return fmt.Errorf("function name required")
}
if err := validateFcnArgs(args[0], args[1:]); err != nil {
return fmt.Errorf("invalid args for %s: %w", args[0], err)
} Type guard
func isChaincodeReportedFailure(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "transaction returned with failure:")
} Try / catch
_, _, err := chaincodeSupport.Execute(txParams, ccName, input)
if err != nil {
var ccErr string
if strings.HasPrefix(err.Error(), "transaction returned with failure: ") {
ccErr = strings.TrimPrefix(err.Error(), "transaction returned with failure: ")
return fmt.Errorf("chaincode rejected tx %s: %s", txParams.TxID, ccErr)
}
return err
} Prevention
- Read the payload embedded in the error — it is the chaincode's own error message.
- Validate all invoke arguments (count, type, format) in the client before submitting.
- Add defensive checks and panic recovery in chaincode functions.
- Check chaincode container logs (`docker logs <cc-container>`) for stack traces on recurring failures.
When it happens
Trigger: The invoked chaincode returns an error response via shim.Error(...), calls panic, or its handler emits ChaincodeMessage_ERROR; Execute/ExecuteLegacyInit then surfaces 'transaction returned with failure: <payload>'.
Common situations: Application-level validation failures in chaincode logic (bad key, insufficient balance); chaincode panics due to nil pointers or unmarshaling bad input; calling a chaincode before it was initialized in pre-2.0 style; explicit access-control rejections inside chaincode.
Related errors
- 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
- Chaincode %s with given certificate hash %v belongs to a dif
- Recv() error: %v, closing connection
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f7a8dce73515e6df.
Report an issue: GitHub.