go runtime_error ai_generated true

rpc error: code = Internal desc = grpc: failed to send message: stream is already closed

ID: go/grpc-stream-already-closed

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-10-05First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.50+ active — — —

Root Cause

Calling Send on a client or server stream after CloseSend or after the stream returned io.EOF. Often caused by concurrent Send from multiple goroutines.

generic

中文

在 CloseSend 之后或流返回 io.EOF 之后调用流的 Send。常由多个 goroutine 并发调用 Send 引起。

Workarounds

  1. 94% success
    for _, m := range msgs {
        if err := stream.Send(m); err != nil {
            if err == io.EOF { break }
            return err
        }
    }
    return stream.CloseSend()
  2. 85% success
    for {
        stream, err := client.Push(ctx)
        if err != nil { return err }
        if err := sendAll(stream, batch); err != nil { return err }
        if _, err := stream.CloseAndRecv(); err != nil { return err }
        if done(batch) { return nil }
    }

Dead Ends

Common approaches that don't work:

  1. 90% fail

    gRPC streams are one-shot; CloseSend is idempotent but does not reopen the stream for sending.

  2. 88% fail

    Subsequent Sends return the same error; the messages are silently dropped.