hashicorp/terraform · error
Error saving -plugin-dir to workspace directory
Error message
Error saving -plugin-dir to workspace directory: %s
What it means
Thrown by init_run.go when c.storePluginPath(c.pluginPath) fails while persisting the -plugin-dir flags to the workspace's .terraformrc/plugin-paths file. The %s is the underlying error.
Solutions
- Verify write permissions on the working directory and .terraform/: `ls -ld . .terraform`.
- Free disk space if the volume is full.
- Ensure the working directory is writable; avoid running init inside a read-only mount.
Example fix
$ chmod u+w . && terraform init -plugin-dir=/opt/plugins
Defensive patterns
Strategy: validation
Validate before calling
// Verify the workspace dir is writable before init with -plugin-dir.
func writableDir(p string) bool {
return os.WriteFile(filepath.Join(p, ".w"), []byte("x"), 0644) == nil
} Prevention
- Run init in a writable working directory.
- Check disk space before init.
- Avoid read-only checkouts in CI for the init step.
When it happens
Trigger: Running `terraform init -plugin-dir=...` (or with TF_PLUGIN_PATHS) when the workspace directory is read-only, full, or the plugin-paths metadata file cannot be written.
Common situations: Read-only checkout in CI; full disk; permissions on the .terraform directory; running init against a module path the user cannot write to.
Related errors
- Error checking configuration
- Failed to write
- cannot create temporary file to update credentials
- Cannot read directory
- cannot read
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/84fb93139a1637d1.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/init_run.go:55
c.Meta.input = initArgs.InputEnabled
c.Meta.targetFlags = initArgs.TargetFlags
c.Meta.compactWarnings = initArgs.CompactWarnings
// Copying the state only happens during backend migration, so setting
// -force-copy implies -migrate-state
if c.forceInitCopy {
c.migrateState = true
}
if len(initArgs.PluginPath) > 0 {
c.pluginPath = initArgs.PluginPath
}
// Get the working directory
path := c.Meta.WorkingDir.RootModuleDir()
if err := c.storePluginPath(c.pluginPath); err != nil {
diags = diags.Append(fmt.Errorf("Error saving -plugin-dir to workspace directory: %s", err))
view.Diagnostics(diags)
return 1
}
// Initialization can be aborted by interruption signals
ctx, done := c.InterruptibleContext(c.CommandContext())
defer done()
if initArgs.FromModule != "" {
src := initArgs.FromModule
empty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory)
if err != nil {
diags = diags.Append(fmt.Errorf("Error validating destination directory: %s", err))
view.Diagnostics(diags)
return 1
}
if !empty {View on GitHub (pinned to d32a084675)