hashicorp/terraform · error

Task Stage %s.

Error message

Task Stage %s.

What it means

Returned by runTaskStage polling when a task stage reaches a terminal failure status (canceled, errored, or failed) AND the summarizers did not produce a final ok continuation. The %s is the TaskStageStatus string (e.g. 'failed', 'errored', 'canceled').

Source

Thrown at internal/cloud/backend_taskStages.go:142

			}
			if ok {
				if b.CLI != nil {
					b.CLI.Output("------------------------------------------------------------------------")
				}
				return true, nil
			}
		case tfe.TaskStageCanceled, tfe.TaskStageErrored, tfe.TaskStageFailed:
			ok, e := processSummarizers(ctx, output, stage, summarizers, errs)
			if e != nil {
				errs = e
			}
			if ok {
				if b.CLI != nil {
					b.CLI.Output("------------------------------------------------------------------------")
				}
				return true, nil
			}
			return false, fmt.Errorf("Task Stage %s.", stage.Status)
		case tfe.TaskStageAwaitingOverride:
			ok, e := processSummarizers(ctx, output, stage, summarizers, errs)
			if e != nil {
				errs = e
			}
			if ok {
				return true, nil
			}
			cont, err := b.processStageOverrides(ctx, output, stage.ID)
			if err != nil {
				errs = errors.Join(errs, err)
			} else {
				if b.CLI != nil {
					b.CLI.Output("------------------------------------------------------------------------")
				}
				return cont, nil
			}
		case tfe.TaskStageUnreachable:

View on GitHub (pinned to c9def3e214)

Solutions

  1. Open the run URL in HCP/TFE and inspect the task stage results to find which task failed and why.
  2. Fix the underlying task (correct task image/version, inputs, secrets) and rerun.
  3. If a mandatory policy failed, override it (with approval) or remediate the config.
  4. If the task was canceled inadvertently, restart the run.

Example fix

// before: poll returns this error when a task fails
return false, fmt.Errorf("Task Stage %s.", stage.Status)
// after (operator side): fix the failing task, then in HCP UI restart the run
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check task stage health before relying on it.
stage, err := b.getTaskStageWithAllOptions(ctx, stageID)
if err == nil && isTerminalFailure(stage.Status) {
    return fmt.Errorf("task stage already %s; aborting before run", stage.Status)
}

Type guard

func isTerminalFailure(s tfe.TaskStageStatus) bool {
    return s == tfe.TaskStageFailed || s == tfe.TaskStageErrored || s == tfe.TaskStageCanceled
}

Try / catch

if err := b.waitTaskStage(ctx, cancelCtx, op, r, stage.ID, label); err != nil {
    if strings.HasPrefix(err.Error(), "Task Stage") {
        // inspect UI results, fix task, optionally override, then re-run
    }
    return err
}

Prevention

When it happens

Trigger: Inside the Poll loop, stage.Status is one of TaskStageCanceled/TaskStageErrored/TaskStageFailed and processSummarizers returned ok == false, so the poll stops with this error.

Common situations: A run task (custom task, SCA scanner, policy enforcement) executed in pre/post-plan failed or was canceled, halting the cloud run; a custom task image errored; operator canceled the task stage manually.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/0989fe4983d930f3. Report an issue: GitHub.