hashicorp/nomad · warning

task %q not started yet. No logs available

Error message

task %q not started yet. No logs available

What it means

The logs endpoint found the requested task in the allocation's TaskStates, but StartedAt is zero, meaning the task has never actually started. Since no logs can exist before a task starts, the endpoint returns HTTP 404 with this message.

Source

Thrown at client/fs_endpoint.go:445

		}

		handleStreamResultError(err, code, encoder)
		return
	}

	// Check that the task is there
	taskState := allocState.TaskStates[req.Task]
	if taskState == nil {
		handleStreamResultError(
			fmt.Errorf("unknown task name %q", req.Task),
			new(int64(http.StatusBadRequest)),
			encoder)
		return
	}

	if taskState.StartedAt.IsZero() {
		handleStreamResultError(
			fmt.Errorf("task %q not started yet. No logs available", req.Task),
			new(int64(http.StatusNotFound)),
			encoder)
		return
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	frames := make(chan *sframer.StreamFrame, streamFramesBuffer)
	errCh := make(chan error)

	// Start streaming
	go func() {
		if err := f.logsImpl(ctx, req.Follow, req.PlainText,
			req.Offset, req.Origin, req.Task, req.LogType, fs, frames); err != nil {
			select {
			case errCh <- err:
			case <-ctx.Done():

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Wait until the task's ClientStatus is running (poll allocation info / TaskStates) before fetching logs.
  2. Check the task's events and RecentEvent list to see why it hasn't started (image pull failure, artifact error).
  3. Retry with backoff if the task is legitimately starting; treat as terminal if the task is stuck pending.
  4. Inspect task startup failures via the alloc's task state events instead of the logs endpoint.

Example fix

// before
logs, err := client.Allocs().Logs(alloc, true, "web", "stdout", nil, nil)
// after
for {
    a, _, _ := client.Allocations().Info(alloc.ID, nil)
    ts := a.TaskStates["web"]
    if ts != nil && !ts.StartedAt.IsZero() {
        break
    }
    time.Sleep(2 * time.Second)
}
logs, err = client.Allocs().Logs(alloc, true, "web", "stdout", nil, nil)
Defensive patterns

Strategy: retry

Validate before calling

a, _, err := client.Allocations().Info(allocID, nil)
ts := a.TaskStates[task]
if ts == nil || ts.StartedAt.IsZero() {
    return fmt.Errorf("task %q not started yet", task)
}

Type guard

func taskStarted(a *api.Allocation, task string) bool {
    ts := a.TaskStates[task]
    return ts != nil && !ts.StartedAt.IsZero()
}

Try / catch

err := retry(10, 2*time.Second, func() error {
    a, _, e := client.Allocations().Info(allocID, nil)
    if e != nil {
        return e
    }
    if !taskStarted(a, task) {
        return errNotStarted
    }
    return fetchLogs(a, task)
})

Prevention

When it happens

Trigger: Requesting logs for a task in pending state, a task waiting on image pull or driver startup, or a task whose start attempt failed — the alloc and task state exist, but the task process has never run.

Common situations: Immediately tailing logs after submitting a job while containers are still starting; tasks stuck pending due to missing artifacts, failed image pull, or placement constraints; dry-run/monitoring scripts hitting logs too early; prestart sidecar tasks that haven't fired yet.

Related errors


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