{"record":{"id":"e3fb7fd05b8c8915","repo":"hyperledger/fabric","slug":"unexpected-response-type-d-for-transaction-s","errorCode":null,"errorMessage":"unexpected response type %d for transaction %s","messagePattern":"unexpected response type (.+?) for transaction (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/chaincode_support.go","lineNumber":199,"sourceCode":"\tif resp.ChaincodeEvent != nil {\n\t\tresp.ChaincodeEvent.ChaincodeId = ccName\n\t\tresp.ChaincodeEvent.TxId = txid\n\t}\n\n\tswitch resp.Type {\n\tcase pb.ChaincodeMessage_COMPLETED:\n\t\tres := &pb.Response{}\n\t\terr := proto.Unmarshal(resp.Payload, res)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.Wrapf(err, \"failed to unmarshal response for transaction %s\", txid)\n\t\t}\n\t\treturn res, resp.ChaincodeEvent, nil\n\n\tcase pb.ChaincodeMessage_ERROR:\n\t\treturn nil, resp.ChaincodeEvent, errors.Errorf(\"transaction returned with failure: %s\", resp.Payload)\n\n\tdefault:\n\t\treturn nil, nil, errors.Errorf(\"unexpected response type %d for transaction %s\", resp.Type, txid)\n\t}\n}\n\n// Invoke will invoke chaincode and return the message containing the response.\n// The chaincode will be launched if it is not already running.\nfunc (cs *ChaincodeSupport) Invoke(txParams *ccprovider.TransactionParams, chaincodeName string, input *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {\n\tccid, cctype, err := cs.CheckInvocation(txParams, chaincodeName, input)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"invalid invocation\")\n\t}\n\n\th, err := cs.Launch(ccid)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn cs.execute(cctype, txParams, chaincodeName, input, h)\n}","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/chaincode_support.go#L181-L217","documentation":"processChaincodeExecutionResult switches on the response ChaincodeMessage_Type and only handles COMPLETED and ERROR. Any other type (e.g. REGISTERED, READY, PUT_STATE, GET_STATE, INVOKE_CHAINCODE arriving where a completion was expected) yields this error. It indicates a protocol-level desynchronization: the peer expected a final transaction result but got an intermediate or unrelated message.","triggerScenarios":"The chaincode handler delivers a message type other than COMPLETED/ERROR as the terminal response of cs.execute — e.g. the chaincode asked the peer to perform state operations (GET_STATE/PUT_STATE) but never sent a final COMPLETED within expectations, or a mixed-version shim/peer misunderstanding produced an unexpected message type. Reached via ChaincodeSupport.Execute / ExecuteLegacyInit.","commonSituations":"Mixed Fabric v1.x chaincode with v2.x peer protocol mismatches; buggy custom shim or decorator altering message flow; chaincode that returns without completing the transaction; corrupted handler state after timeouts/retries.","solutions":["Log resp.Type for the failing txid and check chaincode container logs to see which message flow went wrong.","Ensure peer and chaincode (shim) Fabric versions are compatible; rebuild/redeploy the chaincode against the peer's protos.","Fix chaincode logic so every invocation path ends by returning (which makes the shim send COMPLETED/ERROR).","Remove or correct any custom decorations/middleware that inject or replay chaincode messages.","Retry the transaction after restart if handler state was corrupted; persistent occurrence means a real code/protocol bug."],"exampleFix":"// before: chaincode function returns early without going through shim\nfunc (c *CC) Bad(stub shim.ChaincodeStubInterface) pb.Response {\n    stub.PutState(...)\n    // missing return -> unexpected terminal message\n}\n// after\nfunc (c *CC) Bad(stub shim.ChaincodeStubInterface) pb.Response {\n    if err := stub.PutState(\"k\", []byte(\"v\")); err != nil {\n        return shim.Error(err.Error())\n    }\n    return shim.Success(nil)\n}","handlingStrategy":"try-catch","validationCode":"// sanity-check terminal message before processing\nterminal := msg.Type == pb.ChaincodeMessage_COMPLETED || msg.Type == pb.ChaincodeMessage_ERROR\nif !terminal {\n    return fmt.Errorf(\"handler delivered non-terminal message type %v for tx %s\", msg.Type, txid)\n}","typeGuard":"func isTerminalChaincodeMessage(msg *pb.ChaincodeMessage) bool {\n    return msg != nil &&\n        (msg.Type == pb.ChaincodeMessage_COMPLETED || msg.Type == pb.ChaincodeMessage_ERROR)\n}","tryCatchPattern":"_, _, err := chaincodeSupport.Execute(txParams, ccName, input)\nif err != nil {\n    if strings.Contains(err.Error(), \"unexpected response type\") {\n        // protocol desync: restart handler/chaincode container, verify versions, retry\n        log.Printf(\"protocol mismatch for tx %s: %v\", txParams.TxID, err)\n        return rebuildChaincodeAndRetry(txParams, ccName)\n    }\n    return err\n}","preventionTips":["Keep peer and chaincode (shim) versions protocol-compatible; rebuild chaincode on peer upgrades.","Ensure every chaincode function ends with a return of shim.Success/shim.Error.","Avoid custom message decorators/middleware unless thoroughly tested against the Fabric protocol.","Enable core.chaincode logging at DEBUG to trace the message handshake when diagnosing."],"tags":["protocol","chaincode-message","hyperledger-fabric"],"backgroundTag":"unexpected-response-type","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}