{"record":{"id":"1367a8800b3e5fff","repo":"hashicorp/terraform","slug":"provider-download-blocked-due-to-policy-violations","errorCode":null,"errorMessage":"Provider download blocked due to policy violations. Please review other diagnostics for details.","messagePattern":"Provider download blocked due to policy violations\\. Please review other diagnostics for details\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_policy.go","lineNumber":175,"sourceCode":"\t\t\tVersion:   version,\n\t\t},\n\t})\n\t// We use the root module as the module for provider configs since the version resolution\n\t// is ambiguous, and we do not know which module the provider config belongs to.\n\taddr := addrs.AbsProviderConfig{Provider: provider, Module: addrs.RootModule}\n\tproviderConfig := p.rootModule.ProviderConfigs[provider.Type]\n\n\tif providerConfig != nil {\n\t\t// Annotate the result diagnostics with the local range so that diagnostics can be rendered with both the\n\t\t// policy source and the object being enforced.\n\t\tresult = result.WithLocalRange(providerConfig.DeclRange.Ptr())\n\t}\n\tp.view.PolicyResult(addr.String(), result)\n\tlog.Println(\"[DEBUG] init: policy result for provider\", provider.String(), version, \"overall\", result.Overall)\n\t// Init uses diagnostics as the blocking signal because advisory policies\n\t// may return deny without any error diagnostics.\n\tif result.Diagnostics.HasErrors() {\n\t\treturn fmt.Errorf(\"Provider download blocked due to policy violations. Please review other diagnostics for details.\")\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":157,"sourceCodeEnd":180,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/meta_policy.go#L157-L180","documentation":"Returned by the provider policy hook (providerPolicyHook.ProviderVersionSelected) during terraform init when a configured policy client evaluates the selected provider version and result.Diagnostics.HasErrors() is true. Policy evaluation is advisory-aware: a deny without a hard error diagnostic still blocks, so init uses the diagnostics error flag as the gate. The actual violation details are emitted as separate diagnostics; this message is only the blocking summary telling the user to read them.","triggerScenarios":"terraform init (or any provider installation path) is run in a configuration with a provider policy client configured; policy.EvaluationRequest against provider metadata returns a result whose Diagnostics contain an Error severity, or result.Overall is deny with accompanying error diagnostics.","commonSituations":"Enterprise/regulated environments enforcing OPA/Sentinel-style provider allow-lists; a policy forbidding a provider namespace (e.g. community vs hashicorp), a specific version with a known CVE, or an untrusted registry; policy rules pushed centrally that the local config now violates.","solutions":["Read the companion diagnostics printed immediately before this error — they name the exact policy rule and provider attribute that failed.","Adjust the required_provider version/source in the configuration to satisfy the policy (e.g. pin to an allowed version or switch namespace).","If the violation is intentional and policy is wrong, update the policy rules in the policy source, then re-run terraform init.","Confirm the policy client is pointed at the intended policy bundle; a stale or wrong endpoint can produce spurious denies."],"exampleFix":"// before: policy denies version\nterraform {\n  required_providers {\n    aws = { source = \"hashicorp/aws\", version = \"~> 5.0\" }\n  }\n}\n// after: pin to policy-approved version\nterraform {\n  required_providers {\n    aws = { source = \"hashicorp/aws\", version = \"= 5.40.0\" }\n  }\n}","handlingStrategy":"validation","validationCode":"// Pre-flight: check provider/version against the policy source before init.\n// Requires the same policy client the init hook uses; evaluate and inspect result.Overall.\nres := policyClient.EvaluateProvider(ctx, req)\nif res.Overall == policy.Deny || res.Diagnostics.HasErrors() {\n    return fmt.Errorf(\"would be blocked by provider policy: %s\", res.Diagnostics)\n}","typeGuard":null,"tryCatchPattern":"// Wrap init in automation; on this specific error, surface the policy diagnostics\n// and halt rather than retrying, since retry cannot change policy outcome.\nout, err := runTerraform(\"init\")\nif err != nil && strings.Contains(out, \"Provider download blocked due to policy violations\") {\n    return extractPolicyDiagnostics(out) // parse the preceding diagnostics\n}","preventionTips":["Keep provider versions within the centrally approved allow-list.","Run policy evaluation in CI on the required_providers block before merging.","Document the policy source so developers can self-diagnose denials."],"tags":["terraform","policy","provider","init","security","compliance"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}