hashicorp/terraform · error

Unknown or unexpected policy state: %s

Error message

Unknown or unexpected policy state: %s

What it means

The default branch of checkPolicy()'s status switch: a policy check returned a status not covered by the known cases (PolicyPasses, PolicyErrored, PolicyHardFailed, PolicySoftFailed). Like the cost-estimate equivalent, it means the server returned a policy status this terraform build doesn't recognize.

Source

Thrown at internal/backend/remote/backend_common.go:483

				if err != nil && err != errRunOverridden {
					return fmt.Errorf("Failed to override: %w\n%s\n", err, runURL)
				}

				if err != errRunOverridden {
					if _, err = b.client.PolicyChecks.Override(stopCtx, pc.ID); err != nil {
						return generalError(fmt.Sprintf("Failed to override policy check.\n%s", runURL), err)
					}
				} else {
					runURL := fmt.Sprintf(runHeader, b.hostname, b.organization, op.Workspace, r.ID)
					b.CLI.Output(fmt.Sprintf("The run needs to be manually overridden or discarded.\n%s\n", runURL))
				}
			}

			if b.CLI != nil {
				b.CLI.Output("------------------------------------------------------------------------")
			}
		default:
			return fmt.Errorf("Unknown or unexpected policy state: %s", pc.Status)
		}
	}

	return nil
}

func (b *Remote) confirm(stopCtx context.Context, op *backendrun.Operation, opts *terraform.InputOpts, r *tfe.Run, keyword string) error {
	doneCtx, cancel := context.WithCancel(stopCtx)
	result := make(chan error, 2)

	go func() {
		defer logging.PanicHandler()

		// Make sure we cancel doneCtx before we return
		// so the input command is also canceled.
		defer cancel()

		for {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Upgrade terraform CLI to the latest release to pick up new policy status values.
  2. Align self-hosted TFE and CLI versions.
  3. Report the unknown status string if it reproduces on the latest CLI.
Defensive patterns

Strategy: type-guard

Type guard

var knownPolicyStatuses = map[tfe.PolicyStatus]bool{
    tfe.PolicyPasses: true, tfe.PolicyErrored: true,
    tfe.PolicyHardFailed: true, tfe.PolicySoftFailed: true,
    tfe.PolicyPending: true, tfe.PolicyQueued: true, tfe.PolicyUnreachable: true,
}
func isKnownPolicyStatus(s tfe.PolicyStatus) bool { return knownPolicyStatuses[s] }

Prevention

When it happens

Trigger: checkPolicy() reads pc.Status and it doesn't match any case — a newer HCP/TFE server introduced a policy lifecycle state absent from the bundled go-tfe enum; the raw status is interpolated via %s.

Common situations: Terraform CLI is older than the TFE/HCP server; self-hosted TFE upgraded ahead of the CLI; an experimental policy status shipped server-side.

Related errors


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