hashicorp/terraform · error

The specified plugin cache dir %s cannot be opened: %s

Error message

The specified plugin cache dir %s cannot be opened: %s

What it means

Emitted by `Config.Validate` (cliconfig.go:327-332) when `os.Stat(c.PluginCacheDir)` fails for a non-empty `plugin_cache_dir`. The directory must already exist and be stat-able; Terraform does not create it. The `%s` values are the configured dir and the OS error. The value can come from `plugin_cache_dir` in config or the `TF_PLUGIN_CACHE_DIR` env var.

Source

Thrown at internal/command/cliconfig/cliconfig.go:331

	// Should have zero or one "credentials_helper" blocks
	if len(c.CredentialsHelpers) > 1 {
		diags = diags.Append(
			fmt.Errorf("No more than one credentials_helper block may be specified"),
		)
	}

	// Should have zero or one "provider_installation" blocks
	if len(c.ProviderInstallation) > 1 {
		diags = diags.Append(
			fmt.Errorf("No more than one provider_installation block may be specified"),
		)
	}

	if c.PluginCacheDir != "" {
		_, err := os.Stat(c.PluginCacheDir)
		if err != nil {
			diags = diags.Append(
				fmt.Errorf("The specified plugin cache dir %s cannot be opened: %s", c.PluginCacheDir, err),
			)
		}
	}

	return diags
}

// Merge merges two configurations and returns a third entirely
// new configuration with the two merged.
func (c *Config) Merge(c2 *Config) *Config {
	var result Config
	result.Providers = make(map[string]string)
	result.Provisioners = make(map[string]string)
	maps.Copy(result.Providers, c.Providers)
	maps.Copy(result.Provisioners, c.Provisioners)
	for k, v := range c2.Providers {
		if v1, ok := c.Providers[k]; ok {
			log.Printf("[INFO] Local %s provider configuration '%s' overrides '%s'", k, v, v1)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Create the directory first: `mkdir -p <path>`.
  2. Ensure the directory is writable by the user running Terraform.
  3. If unset is intended, remove `plugin_cache_dir` from config and unset `TF_PLUGIN_CACHE_DIR`.
  4. Fix typos in the configured path.

Example fix

# before
export TF_PLUGIN_CACHE_DIR=/opt/tfplugin-cache   # does not exist
terraform init
# The specified plugin cache dir /opt/tfplugin-cache cannot be opened: stat: no such file or directory

# after
mkdir -p /opt/tfplugin-cache
terraform init
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the plugin cache dir exists and is writable before running.
func pluginCacheOK(dir string) error {
    if dir == "" {
        return nil
    }
    fi, err := os.Stat(dir)
    if err != nil {
        return fmt.Errorf("plugin cache dir %s unusable: %w", dir, err)
    }
    if !fi.IsDir() {
        return fmt.Errorf("%s is not a directory", dir)
    }
    return nil
}

Prevention

When it happens

Trigger: Setting `plugin_cache_dir` (or `TF_PLUGIN_CACHE_DIR`) to a path that does not exist, is not a directory, or is not accessible, then running any Terraform command that loads CLI config.

Common situations: Pointing the cache at a not-yet-created directory; a path on a disconnected mount; permission denied on a shared cache dir; typo in the path.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/be27ff8189618ab4. Report an issue: GitHub.