hashicorp/nomad · error
error stream is no longer running: %w
Error message
error stream is no longer running: %w
What it means
This error is returned by the NDJSON stream's Send method in nomad/stream/ndjson.go when the stream's context has been cancelled while trying to publish an event. It wraps the underlying send error and signals that consumers can no longer receive events because the stream pipeline is shut down. It exists so callers draining a subscription learn immediately that the output channel is dead rather than blocking forever on a send.
Source
Thrown at nomad/stream/ndjson.go:90
}
// Send encodes an object into Newline delimited json. An error is returned
// if json encoding fails or if the stream is no longer running.
func (n *JsonStream) Send(v any) error {
if n.ctx.Err() != nil {
return n.ctx.Err()
}
var buf bytes.Buffer
enc := codec.NewEncoder(&buf, structs.JsonHandleWithExtensions)
err := enc.Encode(v)
if err != nil {
return fmt.Errorf("error marshaling json for stream: %w", err)
}
select {
case <-n.ctx.Done():
return fmt.Errorf("error stream is no longer running: %w", err)
case n.outCh <- &structs.EventJson{Data: buf.Bytes()}:
}
return nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Stop calling Send once the stream is stopped: check stream context cancellation (or the error from Send) and exit the producer loop.
- Ensure the producer goroutine's lifetime is tied to the stream context — use errgroup or a done channel derived from the request context so sends stop when the client disconnects.
- If this surfaces during exec streaming, verify the exec session is not being driven after the raw stream (ExecTaskStreamingRaw) has returned.
- If the wrapped cause is a json.Marshal error on a stopped stream, fix the marshal failure too — that error indicates an event payload with unsupported types or an EncodeValue missing.
Example fix
// before
for event := range events {
if err := stream.Send(event); err != nil {
return err
}
}
// after
for event := range events {
if err := stream.Send(event); err != nil {
if strings.Contains(err.Error(), "error stream is no longer running") {
return nil // client disconnected; stop producer cleanly
}
return err
}
} Defensive patterns
Strategy: try-catch
Validate before calling
select {
case <-streamCtx.Done():
// skip send; stream already stopped
return nil
default:
}
// proceed to stream.Send(event) Type guard
func streamAlive(ctx context.Context) bool {
select {
case <-ctx.Done():
return false
default:
return true
}
} Try / catch
if err := stream.Send(event); err != nil {
if strings.Contains(err.Error(), "error stream is no longer running") {
return nil // graceful shutdown
}
return fmt.Errorf("stream send failed: %w", err)
} Prevention
- Tie the event producer goroutine to the stream's context so sends stop on cancellation.
- Treat any Send error as terminal and exit the loop; never retry sends on a stopped stream.
- Marshal payloads before checking/inside Send flows so marshal failures are reported distinctly.
- In tests, stop the stream only after all Send calls complete (errgroup-style teardown).
When it happens
Trigger: Calling Send on a JsonStream after its context (n.ctx) was cancelled — e.g. the HTTP request ended, the client disconnected, Stop() was called, or the subscription was torn down — while the internal outCh buffer path also failed, so the send falls through to the ctx.Done() branch. Notably it wraps `err` from the preceding json.Marshal, so when marshaling fails on a stopped stream this message appears with the marshal error as the cause.
Common situations: A WebSocket/HTTP streaming client disconnects mid-stream and the handler keeps calling Send for events that arrive afterwards (e.g. exec task streaming, event streams in `nomad monitor`). Also seen in tests like TestJson_Send_After_Stop. A latent bug: the ctx.Done() branch wraps the marshaling `err`, which is nil in the plain cancel case, yielding the odd message 'error stream is no longer running: %!w(<nil>)'.
Related errors
- missing AllocID
- <remote node streaming RPC error relayed from ack.Error>
- subscription closed by server, client should resubscribe
- failed to decode and failed to read buffered data: %w
- failed to decode log endpoint response as JSON: %q
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e1f9e4823ed26b67.
Report an issue: GitHub.