hashicorp/terraform · error

failed to read stacks plugin stored path file: %w

Error message

failed to read stacks plugin stored path file: %w

What it means

Wrapped error from StacksCommand.initPackagesCache when os.ReadFile(cacheStorePath) fails. cacheStorePath is <data-dir>/.stackspluginpath, a small file recording where the stacks plugin cache lives. It is only read when os.Stat reported the file exists, so a read failure here is unusual — typically a race (file deleted between stat and read) or a permission issue.

Source

Thrown at internal/command/stacks.go:394

func (c *StacksCommand) initPackagesCache() (string, error) {
	var pluginPath string
	defaultPluginPath := path.Join(c.CLIConfigDir, StacksPluginDataDir)
	cacheStorePath := path.Join(c.WorkingDir.DataDir(), ".stackspluginpath")

	if _, err := os.Stat(cacheStorePath); err != nil {
		if os.IsNotExist(err) {
			log.Printf("[TRACE] No stacksplugin cache path store at '%s`, using default '%s'", cacheStorePath, defaultPluginPath)
			// Use the default plugin cache path if the file does not exist
			pluginPath = defaultPluginPath
		} else {
			log.Printf("[TRACE] Failed to check the stacksplugin cache path store at '%s', using default '%s'", cacheStorePath, defaultPluginPath)
			// Use the default plugin cache path if there was an error checking the file
			pluginPath = defaultPluginPath
		}
	} else {
		data, err := os.ReadFile(cacheStorePath)
		if err != nil {
			return "", fmt.Errorf("failed to read stacks plugin stored path file: %w", err)
		}
		pluginPath = string(data)
	}

	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 {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Delete .stackspluginpath and re-run; the command will fall back to the default cache path and recreate it.
  2. Ensure the data directory (.terraform) is writable and not modified concurrently.
  3. Avoid running multiple stacks/init commands against the same working dir simultaneously.
  4. Check file permissions/ownership of the data dir.

Example fix

// before
$ terraform stacks init
failed to read stacks plugin stored path file: ...
// after
$ rm -f .terraform/.stackspluginpath
$ terraform stacks init
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: ensure .stackspluginpath is a readable regular file (or absent) before stacks commands
package main

func preflightStacksPluginPath(dataDir string) error {
	p := filepath.Join(dataDir, ".stackspluginpath")
	info, err := os.Stat(p)
	if err != nil { return nil /* absent is fine */ }
	if info.IsDir() { return fmt.Errorf("%s is a directory, expected a file", p) }
	if info.Size() == 0 { return fmt.Errorf("%s is empty; delete it to use the default cache path", p) }
	return nil
}

Prevention

When it happens

Trigger: Running a stacks command when .stackspluginpath exists (stat succeeded) but os.ReadFile then fails — file removed concurrently, permission denied between stat and read, or the path is a directory/special file.

Common situations: Concurrent 'terraform init' / cleanup deleting .stackspluginpath mid-run; permission/ownership change on the data dir; the file got replaced by a directory of the same name; exotic filesystem (NFS) consistency lag.

Related errors


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