hashicorp/terraform · error

failed to read stacks plugin stored path file

Error message

failed to read stacks plugin stored path file: %w

What it means

Thrown inside the stacks plugin path loader when os.ReadFile(cacheStorePath) fails for the .stackspluginpath file. Note the asymmetry: os.Stat already succeeded (we are in the else branch), so this only fires for a narrow window — file deleted between stat and read, permission denied on read, or an I/O error. The path comes from c.WorkingDir.DataDir() joined with `.stackspluginpath`.

Solutions

  1. Re-run `terraform init` to regenerate `.stackspluginpath` and the plugin cache.
  2. Check permissions on the data dir and `.stackspluginpath`: `ls -la .terraform/`.
  3. Avoid running multiple terraform commands concurrently in the same working directory.
  4. Delete `.stackspluginpath` and let Terraform fall back to the default plugin path on next run.

Example fix

# before: stale .stackspluginpath
 rm -f .terraform/.stackspluginpath
 terraform stacks <args>

# after (regenerated)
 terraform init
 terraform stacks <args>
Defensive patterns

Strategy: validation

Validate before calling

// Before reading .stackspluginpath, ensure exclusive access.
f, err := os.OpenFile(cacheStorePath, os.O_RDWR, 0)
if err != nil {
    return "", nil // fall through to default path
}
defer f.Close()
if err := flock.Try(f.Fd()); err != nil {
    return "", fmt.Errorf("another terraform process holds .stackspluginpath: %w", err)
}

Try / catch

data, err := os.ReadFile(cacheStorePath)
if err != nil {
    if os.IsNotExist(err) {
        return defaultPluginPath, nil // file gone; use default
    }
    // transient: stat said it existed, read failed — log and fall back
    log.Printf("[WARN] .stackspluginpath read failed (%v); using default %s", err, defaultPluginPath)
    return defaultPluginPath, nil
}

Prevention

When it happens

Trigger: Another process deletes `.stackspluginpath` between the os.Stat and os.ReadFile calls; file mode denies read to the current user (chmod 000); filesystem I/O error (NFS hiccup, disk failure); symlink loop or dangling symlink that stat followed but read cannot.

Common situations: Concurrent `terraform init` and `terraform stacks` runs racing on the same data dir; permissions altered by a CI step between runs; mounted volume with intermittent I/O errors; `.terraform` dir restored from a tarball that lost ownership.

Related errors


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

Appendix: 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 d32a084675)