{"record":{"id":"a4d7f687d7dfa3e1","repo":"hyperledger/fabric","slug":"chaincode-stream-terminated","errorCode":null,"errorMessage":"chaincode stream terminated","messagePattern":"chaincode stream terminated","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/handler.go","lineNumber":1452,"sourceCode":"\t}\n\tdefer h.TXContexts.Delete(msg.ChannelId, msg.Txid)\n\n\tif err = h.setChaincodeProposal(txParams.SignedProp, txParams.Proposal, msg); err != nil {\n\t\treturn nil, err\n\t}\n\n\th.serialSendAsync(msg)\n\n\tvar ccresp *pb.ChaincodeMessage\n\tselect {\n\tcase ccresp = <-txctx.ResponseNotifier:\n\t\t// response is sent to user or calling chaincode. ChaincodeMessage_ERROR\n\t\t// are typically treated as error\n\tcase <-time.After(timeout):\n\t\terr = errors.New(ErrorExecutionTimeout)\n\t\th.Metrics.ExecuteTimeouts.With(\"chaincode\", h.chaincodeID).Add(1)\n\tcase <-h.streamDone():\n\t\terr = errors.New(ErrorStreamTerminated)\n\t}\n\n\treturn ccresp, err\n}\n\nfunc (h *Handler) setChaincodeProposal(signedProp *pb.SignedProposal, prop *pb.Proposal, msg *pb.ChaincodeMessage) error {\n\tif prop != nil && signedProp == nil {\n\t\treturn errors.New(\"failed getting proposal context. Signed proposal is nil\")\n\t}\n\t// TODO: This doesn't make a lot of sense. Feels like both are required or\n\t// neither should be set. Check with a knowledgeable expert.\n\tif prop != nil {\n\t\tmsg.Proposal = signedProp\n\t}\n\treturn nil\n}\n\nfunc (h *Handler) getCollectionStore(channelID string) privdata.CollectionStore {","sourceCodeStart":1434,"sourceCodeEnd":1470,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler.go#L1434-L1470","documentation":"Returned by Handler.execute when the chaincode's gRPC stream terminates (h.streamDone() fires) while the peer is waiting for a transaction response. The handler creates ErrorStreamTerminated ('chaincode stream terminated') because the chaincode can no longer respond — its connection to the peer was closed.","triggerScenarios":"During execute's select, `case <-h.streamDone()` fires: the chaincode handler stream was closed (chaincode crashed, deregistered, container exited, network drop) before the transaction response arrived.","commonSituations":"Chaincode container crash/OOM mid-transaction; CCaaS build/launch failures; peer-to-chaincode network interruption; chaincode calling os.Exit or panicking during Invoke; peer shutting down.","solutions":["Inspect the chaincode container logs for panic/exit right before the error.","Fix panics in the chaincode (add recover, validate inputs) so it never terminates mid-call.","Check container resource limits (memory/CPU) that could kill the container.","Verify network connectivity between peer and chaincode (docker network, k8s service) and retry the transaction."],"exampleFix":"// chaincode: guard against panics killing the stream\n// before\nfunc (t *Chaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {\n    return t.dispatch(stub)\n}\n// after\nfunc (t *Chaincode) Invoke(stub shim.ChaincodeStubInterface) (resp pb.Response) {\n    defer func() {\n        if r := recover(); r != nil {\n            resp = shim.Error(fmt.Sprintf(\"panic: %v\", r))\n        }\n    }()\n    return t.dispatch(stub)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"stream terminated\") {\n    // chaincode crashed: inspect container logs, fix panic, resubmit transaction\n    log.Printf(\"chaincode stream died during tx %s: %v\", txid, err)\n}","preventionTips":["Add panic recovery in the chaincode Invoke entrypoint.","Set adequate container memory/CPU limits to avoid OOM kills.","Monitor chaincode container restart counts and peer logs for stream errors."],"tags":["hyperledger-fabric","chaincode","stream","crash"],"backgroundTag":"stream-terminated","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"}