hashicorp/terraform · error

Task stage ' ' has invalid status

Error message

Task stage '%s' has invalid status: %s

What it means

Defensive default arm in waitTaskStage's status switch: TFC returned a TaskStage status value the client does not recognize. Like the plan-mode guard, this indicates the TFC/TFE server introduced a new status that this build of go-tfe doesn't handle.

Solutions

  1. Upgrade Terraform to a release whose bundled go-tfe knows the new status.
  2. Or pin the TFC/TFE server version to one compatible with your Terraform build.
  3. If persistent, capture stage.ID and the raw status from TFC support to identify the new value.
Defensive patterns

Strategy: validation

Validate before calling

// Reject unknown statuses explicitly to fail fast on version skew
switch stage.Status {
case /* all known */: // handle
default:
    return fmt.Errorf("unsupported task stage status %q; upgrade Terraform/go-tfe", stage.Status)
}

Type guard

var knownTaskStatuses = map[tfe.TaskStageStatus]bool{
    tfe.TaskStagePending: true, tfe.TaskStageRunning: true, tfe.TaskStagePassed: true,
    tfe.TaskStageCanceled: true, tfe.TaskStageErrored: true, tfe.TaskStageFailed: true,
    tfe.TaskStageAwaitingOverride: true, tfe.TaskStageUnreachable: true,
}
func isKnownTaskStatus(s tfe.TaskStageStatus) bool { return knownTaskStatuses[s] }

Prevention

When it happens

Trigger: stage.Status is a value outside the known set (Pending, Running, Passed, Canceled, Errored, Failed, AwaitingOverride, Unreachable): newer TFC/TFE server than the go-tfe client bundled in this Terraform build.

Common situations: TFC shipped a new task lifecycle status; Terraform core pinned to an older go-tfe; custom TFE build extending statuses; partial API response corruption returning an empty/garbage status string.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/3e91317a4f532875. Report an issue: GitHub.

Appendix: source

Thrown at internal/backend/remote/backend_taskStages.go:51

		}

		switch stage.Status {
		case tfe.TaskStagePending:
			// Waiting for it to start
			return true, nil
		case tfe.TaskStageRunning:
			// not a terminal status so we continue to poll
			return true, nil
		case tfe.TaskStagePassed:
			return false, nil
		case tfe.TaskStageCanceled, tfe.TaskStageErrored, tfe.TaskStageFailed:
			return false, fmt.Errorf("Task Stage '%s': %s.", stage.ID, stage.Status)
		case tfe.TaskStageAwaitingOverride:
			return false, fmt.Errorf("Task Stage '%s' awaiting override.", stage.ID)
		case tfe.TaskStageUnreachable:
			return false, nil
		default:
			return false, fmt.Errorf("Task stage '%s' has invalid status: %s", stage.ID, stage.Status)
		}
	})
}

View on GitHub (pinned to d32a084675)