hashicorp/terraform · error

failed to create stacks plugin stored path file: %w

Error message

failed to create stacks plugin stored path file: %w

What it means

Thrown by StacksCommand.storeStacksPluginPath when os.Create fails to make the .terraform/.stackspluginpath marker file that records where the stacks plugin is cached. The stacks subcommand caches the discovered stacksplugin binary location so subsequent runs skip re-discovery; persisting that location requires a writable data directory. The wrapped %w carries the underlying os.PathError (permission, read-only filesystem, or missing parent dir).

Source

Thrown at internal/command/stacks.go:415

	}

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

	return pluginPath, nil
}

func (c *StacksCommand) storeStacksPluginPath(pluginCachePath string) error {
	f, err := os.Create(path.Join(c.WorkingDir.DataDir(), ".stackspluginpath"))
	if err != nil {
		return fmt.Errorf("failed to create stacks plugin stored path file: %w", err)
	}
	defer f.Close()
	f.WriteString(pluginCachePath)

	return nil
}

// Run runs the stacks command with the given arguments.
func (c *StacksCommand) 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 stacks command.
func (c *StacksCommand) Help() string {
	helpText := new(bytes.Buffer)
	errorText := new(bytes.Buffer)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify the data dir is writable: ls -la .terraform/ and ensure the current user owns it.
  2. Re-run `terraform init` in the same directory as the user/UID that will run `terraform stacks`, so ownership matches.
  3. Free disk space or remount the workspace read-write if the .terraform dir is on a read-only mount.
  4. If sharing the dir across users, set group write: chmod -R g+w .terraform and ensure matching group ownership.

Example fix

# before: running stacks as a user that does not own .terraform
sudo terraform stacks init

# after: run as the owning user, or fix ownership
chown -R $USER:$USER .terraform
terraform stacks init
Defensive patterns

Strategy: validation

Validate before calling

// before calling storeStacksPluginPath, ensure the data dir is writable
import "os"

func dataDirWritable(dir string) error {
    info, err := os.Stat(dir)
    if err != nil {
        return err
    }
    if !info.IsDir() {
        return fmt.Errorf("%s is not a directory", dir)
    }
    f, err := os.CreateTemp(dir, ".write-probe-*")
    if err != nil {
        return fmt.Errorf("data dir %s is not writable: %w", dir, err)
    }
    f.Close()
    os.Remove(f.Name())
    return nil
}

Prevention

When it happens

Trigger: Running `terraform stacks` (or any stacks subcommand) after the stacks plugin has been located, when the working directory's data dir (.terraform/) is read-only, owned by another user, on a full disk, or when the parent directory was removed between initPackagesCache and storeStacksPluginPath. Concretely: os.Create(path.Join(c.WorkingDir.DataDir(), ".stackspluginpath")) returns a non-nil error.

Common situations: CI runners that mark .terraform/ read-only after `terraform init`; containers with a read-only volume mount for the workspace; running as a different UID than the one that ran init; NFS/network filesystem permission mismatches; disk-full ephemeral runners.

Related errors


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