{"record":{"id":"84978be2f85d8f85","repo":"hyperledger/fabric","slug":"deliver-completed-with-status-s-before-txid-rec","errorCode":null,"errorMessage":"deliver completed with status (%s) before txid received","messagePattern":"deliver completed with status \\((.+?)\\) before txid received","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/chaincode/common.go","lineNumber":746,"sourceCode":"\t\t\terr = errors.WithMessagef(err, \"error receiving from deliver filtered at %s\", dc.Address)\n\t\t\tdg.setError(err)\n\t\t\treturn\n\t\t}\n\t\tswitch r := resp.Type.(type) {\n\t\tcase *pb.DeliverResponse_FilteredBlock:\n\t\t\tfilteredTransactions := r.FilteredBlock.FilteredTransactions\n\t\t\tfor _, tx := range filteredTransactions {\n\t\t\t\tif tx.Txid == dg.TxID {\n\t\t\t\t\tlogger.Infof(\"txid [%s] committed with status (%s) at %s\", dg.TxID, tx.TxValidationCode, dc.Address)\n\t\t\t\t\tif tx.TxValidationCode != pb.TxValidationCode_VALID {\n\t\t\t\t\t\terr = errors.Errorf(\"transaction invalidated with status (%s)\", tx.TxValidationCode)\n\t\t\t\t\t\tdg.setError(err)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\tcase *pb.DeliverResponse_Status:\n\t\t\terr = errors.Errorf(\"deliver completed with status (%s) before txid received\", r.Status)\n\t\t\tdg.setError(err)\n\t\t\treturn\n\t\tdefault:\n\t\t\terr = errors.Errorf(\"received unexpected response type (%T) from %s\", r, dc.Address)\n\t\t\tdg.setError(err)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// WaitForWG waits for the deliverGroup's wait group and closes\n// the channel when ready\nfunc (dg *DeliverGroup) WaitForWG(readyCh chan struct{}) {\n\tdg.wg.Wait()\n\tclose(readyCh)\n}\n\n// setError serializes an error for the deliverGroup","sourceCodeStart":728,"sourceCodeEnd":764,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/chaincode/common.go#L728-L764","documentation":"The deliver stream closed by sending a final DeliverResponse_Status (e.g. FORBIDDEN, NOT_FOUND, SERVICE_UNAVAILABLE) before the awaited txid appeared in any block. This indicates the deliver session ended prematurely rather than delivering the transaction event.","triggerScenarios":"Peer's deliver service rejects or closes the stream — wrong channel name (NOT_FOUND), ACL denying the client's deliver role (FORBIDDEN), peer restarting, or deliver service unavailable — while ClientWait is still waiting for the txid.","commonSituations":"Typo in --channelID; client identity lacking the channel-readers ACL; peer outage mid-wait; TLS identity not enrolled for the channel.","solutions":["Confirm --channelID is correct and the peer is joined to that channel","Check the client identity satisfies the channel's readers/deliver ACL policy","Read the status code in the message and peer logs; fix the underlying deliver rejection","Retry the wait after the peer recovers, or query commit status via an alternate peer"],"exampleFix":"// before\npeer chaincode invoke -o orderer:7050 -C mychanel -n mycc ...  # typo'd channel\n// after\npeer chaincode invoke -o orderer:7050 -C mychannel -n mycc ...","handlingStrategy":"type-guard","validationCode":"// pre-check channel membership and ACLs\nif !isPeerJoinedToChannel(peer, channelID) { return fmt.Errorf(\"peer not joined to %s\", channelID) }","typeGuard":"func isDeliverStatusError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"deliver completed with status (\")\n}","tryCatchPattern":"if isDeliverStatusError(err) {\n    status := extractBetween(err.Error(), \"status (\", \")\")\n    // FORBIDDEN → fix ACLs/identity; NOT_FOUND → fix channel name; otherwise check peer health\n}","preventionTips":["Double-check --channelID spelling","Ensure the invoking identity has channel reader privileges","Monitor peer uptime; avoid single-peer deliver waits in production"],"tags":["fabric","deliver","acl","stream-closed"],"backgroundTag":"deliver-stream-status-error","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"}