hashicorp/terraform · error
failed to read module manifest
Error message
failed to read module manifest: %s
What it means
When constructing a config loader, Terraform reads the module manifest snapshot (a JSON file tracking installed modules under .terraform/modules/). If this file cannot be read or parsed — corrupt JSON, missing file when modules were partially installed, or a permission error — the loader cannot be created and the error propagates.
Solutions
- Run terraform init to regenerate the module manifest from scratch.
- If .terraform is corrupt, remove it entirely: rm -rf .terraform && terraform init.
- Check file permissions on .terraform/modules/modules.json and ensure the Terraform process can read it.
- Avoid running multiple terraform init processes concurrently in the same working directory.
Example fix
# before — partial/corrupt module manifest from interrupted init terraform plan # → error # after — clean reinitialize rm -rf .terraform terraform init terraform plan
Defensive patterns
Strategy: validation
Validate before calling
// Verify the module manifest is readable before plan
// Shell pre-check:
// terraform init -input=false # regenerates manifest if corrupt
// If init itself fails:
// rm -rf .terraform && terraform init
// Go-side (embedding Terraform): wrap loader creation in error handling
loader, err := configload.NewLoader(cfg)
if err != nil {
log.Printf("module manifest load failed, attempting clean init: %v", err)
os.RemoveAll(filepath.Join(workingDir, ".terraform"))
// re-run init, then retry
} Prevention
- Avoid interrupting terraform init mid-run; if interrupted, clean .terraform before retrying.
- Never partially restore .terraform from backup — either restore fully or re-init.
- Do not run multiple terraform init processes concurrently in the same directory.
- Add rm -rf .terraform as a recovery step in CI when init fails with manifest errors.
When it happens
Trigger: Loader instantiation calls readModuleManifestSnapshot(), which fails. Triggered by: .terraform/modules/modules.json being corrupt or truncated, a partial terraform init that wrote a half-finished manifest, file permission issues on the modules directory, or a race condition where the manifest was being written when Terraform tried to read it.
Common situations: A previous terraform init was interrupted (Ctrl+C, crash, OOM kill), leaving a partial manifest file. The .terraform directory was partially deleted or restored from backup. Filesystem corruption on the modules directory. Concurrent Terraform processes racing on the same working directory.
Related errors
- cannot create temporary file to update credentials
- cannot read
- Error creating temporary directory
- Error getting pwd
- failed to create directory
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/c501f00f025d424b.
Report an issue: GitHub.
Appendix: source
Thrown at internal/configs/configload/loader.go:92
parser := configs.NewParser(fs)
reg := registry.NewClient(config.Services, nil)
ret := &Loader{
parser: parser,
modules: moduleMgr{
FS: afero.Afero{Fs: fs},
CanInstall: true,
Dir: config.ModulesDir,
Services: config.Services,
Registry: reg,
},
parserOpts: make([]configs.Option, 0),
}
err := ret.modules.readModuleManifestSnapshot()
if err != nil {
return nil, fmt.Errorf("failed to read module manifest: %s", err)
}
if config.IncludeQueryFiles {
ret.parserOpts = append(ret.parserOpts, configs.MatchQueryFiles())
}
if config.IncludeStateMigrateFiles {
ret.parserOpts = append(ret.parserOpts, configs.MatchStateMigrateFiles())
}
return ret, nil
}
// ModulesDir returns the path to the directory where the loader will look for
// the local cache of remote module packages.
func (l *Loader) ModulesDir() string {
return l.modules.Dir
}View on GitHub (pinned to d32a084675)