hyperledger/fabric · error
stream %d aborted
Error message
stream %d aborted
What it means
Stream.SendWithReport checks whether the stream was canceled before sending; if so, it returns an error whose message is the stored abortReason, typically "stream N aborted". Streams are aborted when the remote node fails, the connection dies, or the stream is reaped due to inactivity/queue overflow, so consensus messages or submit forwards cannot be delivered.
Source
Thrown at orderer/common/cluster/stream.go:59
}
// StreamOperation denotes an operation done by a stream, such a Send or Receive.
type StreamOperation func() (*orderer.StepResponse, error)
// Canceled returns whether the stream was canceled.
func (stream *Stream) Canceled() bool {
return atomic.LoadUint32(stream.canceled) == uint32(1)
}
// Send sends the given request to the remote cluster member.
func (stream *Stream) Send(request *orderer.StepRequest) error {
return stream.SendWithReport(request, func(_ error) {})
}
// SendWithReport sends the given request to the remote cluster member and invokes report on the send result.
func (stream *Stream) SendWithReport(request *orderer.StepRequest, report func(error)) error {
if stream.Canceled() {
return errors.New(stream.abortReason.Load().(string))
}
var allowDrop bool
// We want to drop consensus transactions if the remote node cannot keep up with us,
// otherwise we'll slow down the entire FSM.
if request.GetConsensusRequest() != nil {
allowDrop = true
}
return stream.sendOrDrop(request, allowDrop, report)
}
// sendOrDrop sends the given request to the remote cluster member, or drops it
// if it is a consensus request and the queue is full.
func (stream *Stream) sendOrDrop(request *orderer.StepRequest, allowDrop bool, report func(error)) error {
msgType := "transaction"
if allowDrop {
msgType = "consensus"
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Check connectivity and health of the remote ordering node; restart it if it crashed
- Verify TLS certificates and mutual auth between cluster members
- Increase SendBufferSize / address remote slowness so streams are not aborted for being unable to keep up
- Retry the send — the stream layer will establish a new stream on the next connection to the recovered node
Defensive patterns
Strategy: try-catch
Validate before calling
if stream.Canceled() { return fmt.Errorf("stream aborted: %s", stream.AbortReason()) } Try / catch
err := stream.Send(consensusReq)
if err != nil {
if strings.Contains(err.Error(), "aborted") {
// stream dead: reconnect and resend on a fresh stream
return reconnectAndResend(consensusReq)
}
return err
} Prevention
- Monitor remote node health; streams abort when peers crash
- Tune SendBufferSize so slow remotes aren't culled
- Reconnect promptly on abort to minimize consensus downtime
- Check TLS/network stability between cluster members
When it happens
Trigger: Send is called on a Stream that was already canceled (stream.Canceled() true) because the remote endpoint aborted it — e.g. worker pool detected a dropped connection, the abort futures fired, or the connection was closed by the remote node.
Common situations: Remote ordering node crashed or restarted while the local node still held a stream to it; network partition; remote node too slow to drain consensus messages and its connection culled; TLS handshake failure mid-session aborting the stream.
Related errors
- response is of type %v, but expected a block
- orderer `%s` hung up without sending status
- invalid request object
- request message is nil
- stream %d is stale
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/e031a552d9375880.
Report an issue: GitHub.