hashicorp/terraform · error

failed to initialize cloudplugin cache directory: %w

Error message

failed to initialize cloudplugin cache directory: %w

What it means

Returned by CloudCommand.initPackagesCache (cloud.go:249) when os.MkdirAll fails to create the cloudplugin cache directory under the data dir (TF_DATA_DIR, default .terraform). This cache holds the downloaded terraform-cloudplugin binary; without it, the `terraform cloud` / packages-based cloud subcommands cannot stage the plugin. The error is wrapped with %w so callers can inspect the underlying os.PathError.

Source

Thrown at internal/command/cloud.go:256

		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Warning,
			"Cloud plugin development overrides are in effect",
			detailMsg,
		))
	}
	log.Printf("[TRACE] plugin %q binary located at %q%s", version.ProductVersion, version.Path, cacheTraceMsg)
	c.pluginBinary = version.Path
	return diags
}

func (c *CloudCommand) initPackagesCache() (string, error) {
	packagesPath := path.Join(c.WorkingDir.DataDir(), CloudPluginDataDir)

	if info, err := os.Stat(packagesPath); err != nil || !info.IsDir() {
		log.Printf("[TRACE] initialized cloudplugin cache directory at %q", packagesPath)
		err = os.MkdirAll(packagesPath, 0755)
		if err != nil {
			return "", fmt.Errorf("failed to initialize cloudplugin cache directory: %w", err)
		}
	} else {
		log.Printf("[TRACE] cloudplugin cache directory found at %q", packagesPath)
	}

	return packagesPath, nil
}

// Run runs the cloud command with the given arguments.
func (c *CloudCommand) Run(args []string) int {
	args = c.Meta.process(args)
	return c.realRun(args, c.Meta.Streams.Stdout.File, c.Meta.Streams.Stderr.File)
}

// Help returns help text for the cloud command.
func (c *CloudCommand) Help() string {
	helpText := new(bytes.Buffer)
	if exitCode := c.realRun([]string{}, helpText, io.Discard); exitCode != 0 {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify TF_DATA_DIR (or the working directory's .terraform) is writable: `ls -ld .terraform` and `mkdir -p .terraform/plugins && rm -d .terraform/plugins`.
  2. If a regular file occupies the cache path, remove it: `ls -la .terraform/cloudplugin` and `rm` it if it is a file.
  3. Unset or repoint TF_DATA_DIR to a writable directory and retry.
  4. In read-only containers, mount a writable volume at the data dir or set TF_DATA_DIR=/tmp/tf-data.
  5. Free disk space / fix permissions on the parent directory.

Example fix

# before
$ terraform cloud
failed to initialize cloudplugin cache directory: mkdir .terraform/cloudplugin: read-only file system

# after: mount a writable volume / repoint data dir
$ export TF_DATA_DIR=/tmp/tf-data
$ terraform cloud
Defensive patterns

Strategy: validation

Validate before calling

// Validate the cloudplugin cache path before initialization
packagesPath := filepath.Join(dataDir, "cloudplugin")
if info, err := os.Stat(packagesPath); err == nil && !info.IsDir() {
    return fmt.Errorf("%s exists and is not a directory; remove it", packagesPath)
}
if err := os.MkdirAll(filepath.Dir(packagesPath), 0755); err != nil {
    return fmt.Errorf("cannot create parent of cloudplugin cache: %w", err)
}

Try / catch

// On cache init failure, fall back to disabling the cloud subcommand rather than crashing the whole CLI.
if _, err := c.initPackagesCache(); err != nil {
    log.Printf("warning: cloudplugin cache unavailable (%v); `terraform cloud` will be disabled", err)
    c.cloudDisabled = true
}

Prevention

When it happens

Trigger: os.MkdirAll(packagesPath, 0755) fails: TF_DATA_DIR points to a read-only or non-existent parent that cannot be created, permission denied on a path component, disk full, or a file (not directory) already exists at packagesPath blocking MkdirAll.

Common situations: TF_DATA_DIR set to a read-only location in CI; a previous run created a file at the cache path; the data dir is on a network share that refuses directory creation; running as a user without write permission to the working directory's .terraform; container with read-only root filesystem and no writable volume for the data dir.

Related errors


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