{"record":{"id":"f4a17611c9256fcc","repo":"hashicorp/terraform","slug":"no-more-than-one-provider-installation-block-may-b","errorCode":null,"errorMessage":"No more than one provider_installation block may be specified","messagePattern":"No more than one provider_installation block may be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/cliconfig/cliconfig.go","lineNumber":323,"sourceCode":"\t\t_, err := svchost.ForComparison(givenHost)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(\n\t\t\t\tfmt.Errorf(\"The credentials %q block has an invalid hostname: %s\", givenHost, err),\n\t\t\t)\n\t\t}\n\t}\n\n\t// Should have zero or one \"credentials_helper\" blocks\n\tif len(c.CredentialsHelpers) > 1 {\n\t\tdiags = diags.Append(\n\t\t\tfmt.Errorf(\"No more than one credentials_helper block may be specified\"),\n\t\t)\n\t}\n\n\t// Should have zero or one \"provider_installation\" blocks\n\tif len(c.ProviderInstallation) > 1 {\n\t\tdiags = diags.Append(\n\t\t\tfmt.Errorf(\"No more than one provider_installation block may be specified\"),\n\t\t)\n\t}\n\n\tif c.PluginCacheDir != \"\" {\n\t\t_, err := os.Stat(c.PluginCacheDir)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(\n\t\t\t\tfmt.Errorf(\"The specified plugin cache dir %s cannot be opened: %s\", c.PluginCacheDir, err),\n\t\t\t)\n\t\t}\n\t}\n\n\treturn diags\n}\n\n// Merge merges two configurations and returns a third entirely\n// new configuration with the two merged.\nfunc (c *Config) Merge(c2 *Config) *Config {","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/cliconfig/cliconfig.go#L305-L341","documentation":"Thrown when the CLI configuration contains more than one provider_installation block. Terraform permits at most one provider_installation block to keep provider installation methods unambiguous. Multiple installation methods should be nested as separate method blocks within a single provider_installation block.","triggerScenarios":"len(c.ProviderInstallation) > 1 after parsing. Occurs when multiple provider_installation blocks are defined in one file or appear across merged config files.","commonSituations":"Adding a new provider_installation block without removing the old one; merging config files that each define provider_installation; copy-paste from documentation alongside existing config.","solutions":["Consolidate into a single provider_installation block with multiple nested method blocks (filesystem_mirror, direct, etc.)","Remove duplicate provider_installation blocks","Review all config files in the merge chain"],"exampleFix":"// before\nprovider_installation {\n  filesystem_mirror { path = \"/local/mirror\" }\n}\nprovider_installation {\n  direct {}\n}\n\n// after\nprovider_installation {\n  filesystem_mirror { path = \"/local/mirror\" }\n  direct {}\n}","handlingStrategy":"validation","validationCode":"// Count provider_installation blocks in config before deployment\nfunc countProviderInstallations(path string) (int, error) {\n    src, err := os.ReadFile(path)\n    if err != nil {\n        return 0, err\n    }\n    return strings.Count(string(src), \"provider_installation\"), nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a single provider_installation block with multiple nested method blocks (filesystem_mirror, direct, etc.)","Avoid defining provider_installation in multiple merged config files","Review full config after merging files for duplicate top-level blocks","Consolidate provider installation methods rather than duplicating the block"],"tags":["cli-config","provider-installation","validation","duplicate"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}