hashicorp/nomad · error

received an error from stdout log stream: %v

Error message

received an error from stdout log stream: %v

What it means

nomad alloc logs tails an allocation's stdout log via the Nomad API's streaming Logs() call. When the background stream goroutine delivers an error on its error channel mid-stream, tailMultipleFiles aborts and wraps it in this message. It means the stdout log streaming connection failed after setup succeeded (server disconnect, allocation exit, network drop, etc.).

Source

Thrown at command/alloc_logs.go:409

	// Generate our logging UI that doesn't add any additional formatting to
	// output strings.
	logUI, err := ui.NewLogUI(l.Ui)
	if err != nil {
		return err
	}

	// Enter the main loop where we listen for log frames, errors, and a cancel
	// signal. Any error at this point will result in the stream being ended,
	// therefore should result in this command exiting. Otherwise, we would
	// just be printing a single stream, which might be hard to notice for the
	// user.
	for {
		select {
		case <-signalCh:
			return nil
		case stdoutErr := <-stdoutErrCh:
			return fmt.Errorf("received an error from stdout log stream: %v", stdoutErr)
		case stdoutFrame := <-stdoutFrames:
			if stdoutFrame != nil {
				logUI.Output(string(stdoutFrame.Data))
			}
		case stderrErr := <-stderrErrCh:
			return fmt.Errorf("received an error from stderr log stream: %v", stderrErr)
		case stderrFrame := <-stderrFrames:
			if stderrFrame != nil {
				logUI.Warn(string(stderrFrame.Data))
			}
		}
	}
}

func lookupAllocTask(alloc *api.Allocation) (string, error) {
	tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup)
	if tg == nil {
		return "", fmt.Errorf("Could not find allocation task group: %s", alloc.TaskGroup)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Re-run `nomad alloc logs -f <alloc-id>`; if the allocation was rescheduled, tail the new allocation ID (`nomad status <job>` to find it).
  2. Check connectivity to the Nomad server/agent and any proxy/LB idle timeouts in the streaming path; raise keepalive/idle timeouts.
  3. Verify the allocation is still running with `nomad alloc status <alloc-id>` before tailing; if it exited, read the logs without -f or check with `nomad alloc logs -job`.
  4. If errors recur, check server logs (`nomad monitor`) and client node health for the node hosting the allocation.

Example fix

// before: one-shot tail that dies on stream error
err := c.tailMultipleFiles(client, alloc)

// after: retry with backoff on transient stream errors
for attempt := 0; attempt < 3; attempt++ {
    err := c.tailMultipleFiles(client, alloc)
    if err == nil || !isRetryableStreamErr(err) {
        return err
    }
    time.Sleep(time.Duration(attempt+1) * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

alloc, _, err := client.Allocations().Info(allocID, nil)
if err != nil { return err }
if alloc.ClientStatus != "running" {
    // allocation may exit mid-tail; fetch logs without -f instead
    return client.AllocFS().Logs(alloc, false, task, api.FSLogNameStdout,
        api.OffsetStart, 0, nil, nil) // handle err
}
return nil

Type guard

func streamAlive(errCh <-chan error) bool {
    select {
    case err, ok := <-errCh:
        return ok && err == nil
    default:
        return true
    }
}

Try / catch

err := c.tailMultipleFiles(client, alloc)
if err != nil && strings.Contains(err.Error(), "received an error from stdout log stream") {
    // transient stream drop: check alloc status, then retry with backoff
    alloc, _, _ := client.Allocations().Info(allocID, nil)
    if alloc != nil && alloc.ClientStatus == "running" {
        return retryTail(client, alloc) // bounded retries
    }
}

Prevention

When it happens

Trigger: Running `nomad alloc logs -f <alloc>` (tailMultipleFiles via Run) and the AllocFS().Logs(... FSLogNameStdout ...) stream errors while tailing: the allocation terminates and the server closes the stream, the Nomad client node restarts, or the HTTP streaming connection is dropped (proxy timeout, network interruption).

Common situations: Tailing logs of a short-lived/batch job whose allocation completes mid-tail; unstable VPN or network to the Nomad server; a load balancer killing long-lived streaming connections; Nomad client node failure or rescheduling of the allocation.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/f4226ef4b1ba998e. Report an issue: GitHub.