hashicorp/terraform · error

soft failed.

Error message

%s soft failed.
%s

What it means

Returned for a soft-failed policy check (tfe.PolicySoftFailed) when interactive override is not possible. The conditions are: the operation is a plan, OR no UI input/output is available, OR the policy is not overridable, OR the token lacks CanOverride permission. The message appends the run URL for manual action.

Solutions

  1. Fix the configuration to comply with the policy rather than overriding.
  2. If override is legitimate, grant the token's team 'Override Soft Failed Policies' permission and run interactively at apply time.
  3. Override the run manually via the run URL shown in the error (TFC UI or API).
  4. Adjust the policy enforcement from soft-mandatory to advisory if the violation is acceptable by design.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure override capability before relying on interactive override at apply time.
func canOverride(pc *tfe.PolicyCheck, op *backendrun.Operation) bool {
    return op.Type != backendrun.OperationTypePlan &&
        op.UIOut != nil && op.UIIn != nil &&
        pc.Actions.IsOverridable && pc.Permissions.CanOverride
}

Try / catch

// When soft-fail is expected in CI, pre-check override permission and fail with guidance.
if pc.Status == tfe.PolicySoftFailed && !canOverride(pc, op) {
    return fmt.Errorf("soft policy failed and override unavailable; fix config or grant override permission")
}

Prevention

When it happens

Trigger: pc.Status == tfe.PolicySoftFailed AND (op.Type == plan OR op.UIOut/UIIn == nil OR !pc.Actions.IsOverridable OR !pc.Permissions.CanOverride). The soft-mandatory policy failed but the current context cannot prompt or is not authorized to override.

Common situations: CI/automated run with no TTY where a soft policy fails; plan-stage policy check (override is only offered at apply); token's team lacks 'Override Soft Failed Policies' permission; policy set marked non-overridable.

Related errors


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

Appendix: source

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

			}
		}

		switch pc.Status {
		case tfe.PolicyPasses:
			if (r.HasChanges && op.Type == backendrun.OperationTypeApply || i < len(r.PolicyChecks)-1) && b.CLI != nil {
				b.CLI.Output("\n------------------------------------------------------------------------")
			}
			continue
		case tfe.PolicyErrored:
			return fmt.Errorf("%s errored.", msgPrefix)
		case tfe.PolicyHardFailed:
			return fmt.Errorf("%s hard failed.", msgPrefix)
		case tfe.PolicySoftFailed:
			runURL := fmt.Sprintf(runHeaderErr, b.hostname, b.organization, op.Workspace, r.ID)

			if op.Type == backendrun.OperationTypePlan || op.UIOut == nil || op.UIIn == nil ||
				!pc.Actions.IsOverridable || !pc.Permissions.CanOverride {
				return fmt.Errorf("%s soft failed.\n%s", msgPrefix, runURL)
			}

			if op.AutoApprove {
				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 {
				opts := &terraform.InputOpts{
					Id:          "override",
					Query:       "\nDo you want to override the soft failed policy check?",
					Description: "Only 'override' will be accepted to override.",
				}
				err = b.confirm(stopCtx, op, opts, r, "override")
				if err != nil && err != errRunOverridden {
					return fmt.Errorf("Failed to override: %w\n%s\n", err, runURL)
				}

				if err != errRunOverridden {

View on GitHub (pinned to d32a084675)