hashicorp/terraform · error
hard failed.
Error message
%s hard failed.
What it means
Returned when a policy check's status is tfe.PolicyHardFailed. Hard-mandatory policy violations cannot be overridden by any user; the run is permanently blocked until the configuration complies. There is no override path, unlike soft failures.
Solutions
- Read the policy failure detail in the TFC/TFE UI to see which rule failed and why.
- Modify the Terraform configuration to satisfy the hard-mandatory policy.
- If the policy itself is wrong, change its enforcement level (requires policy admin) - but do not weaken governance lightly.
- Re-plan once the configuration complies.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight policy simulation is not directly available, but you can static-check // configs against known-hard rules before pushing. // Use 'terraform validate' + custom Conftest/OPA checks mirroring hard-mandatory rules.
Try / catch
// Hard fails are non-recoverable; do not retry, route to the config owner.
if pc.Status == tfe.PolicyHardFailed {
return fmt.Errorf("hard-mandatory policy failed; config must be changed - no override possible")
} Prevention
- Mirror hard-mandatory policies as local pre-commit/CI checks (Conftest, OPA) so failures surface before reaching TFC.
- Document each hard-mandatory policy with example-compliant configs.
- Notify governance owners when adding/tightening hard policies so teams can adapt.
When it happens
Trigger: pc.Status == tfe.PolicyHardFailed during checkPolicy. A policy enforced at 'hard-mandatory' level evaluated to false (e.g. disallowed instance type, forbidden region, missing required tags).
Common situations: Config violates a governance policy (banned provider, public S3 bucket, non-approved AMI); policy enforcement was recently tightened; new policy set added to the workspace.
Related errors
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/f24f611838439678.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote/backend_common.go:445
line = append(line, l...)
}
if next || len(line) > 0 {
b.CLI.Output(b.Colorize().Color(string(line)))
}
}
}
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.",
}View on GitHub (pinned to d32a084675)