{"record":{"id":"be27ff8189618ab4","repo":"hashicorp/terraform","slug":"the-specified-plugin-cache-dir-s-cannot-be-opened","errorCode":null,"errorMessage":"The specified plugin cache dir %s cannot be opened: %s","messagePattern":"The specified plugin cache dir (.+?) cannot be opened: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/cliconfig/cliconfig.go","lineNumber":331,"sourceCode":"\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 {\n\tvar result Config\n\tresult.Providers = make(map[string]string)\n\tresult.Provisioners = make(map[string]string)\n\tmaps.Copy(result.Providers, c.Providers)\n\tmaps.Copy(result.Provisioners, c.Provisioners)\n\tfor k, v := range c2.Providers {\n\t\tif v1, ok := c.Providers[k]; ok {\n\t\t\tlog.Printf(\"[INFO] Local %s provider configuration '%s' overrides '%s'\", k, v, v1)","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/cliconfig/cliconfig.go#L313-L349","documentation":"Thrown when os.Stat fails on the configured plugin_cache_dir path. Terraform validates that the plugin cache directory exists and is accessible so that provider downloads can be cached there. The error includes the configured path and the underlying stat error.","triggerScenarios":"c.PluginCacheDir is non-empty but os.Stat(c.PluginCacheDir) returns an error: the directory does not exist, permissions are insufficient, or the path is invalid.","commonSituations":"plugin_cache_dir set to a nonexistent path; directory deleted after config was written; permissions changed; path copied from a different machine/environment; relative path resolved against an unexpected working directory.","solutions":["Create the directory: mkdir -p <plugin_cache_dir>","Check permissions: chmod 755 <plugin_cache_dir>","Use an absolute path for plugin_cache_dir in the config","Remove or comment out plugin_cache_dir if you do not need caching"],"exampleFix":"// before\nplugin_cache_dir = \"~/terraform-plugins\"\n\n// after\nplugin_cache_dir = \"/home/user/.terraform.d/plugin-cache\"","handlingStrategy":"validation","validationCode":"// Verify plugin cache dir exists and is a directory before running terraform\nfunc checkPluginCacheDir(path string) error {\n    if path == \"\" {\n        return nil // not configured, nothing to check\n    }\n    info, err := os.Stat(path)\n    if err != nil {\n        return fmt.Errorf(\"plugin cache dir %s not accessible: %w\", path, err)\n    }\n    if !info.IsDir() {\n        return fmt.Errorf(\"plugin cache path %s is not a directory\", path)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for plugin_cache_dir in the config","Ensure the cache directory exists before first run: mkdir -p <path>","Set appropriate permissions (755) on the cache directory","Remove plugin_cache_dir from config if caching is not needed"],"tags":["cli-config","plugin-cache","filesystem","validation"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}