hashicorp/terraform · error

Failed to refresh module manifest: %w

Error message

Failed to refresh module manifest: %w

What it means

Wrapped error from ModulesCommand.internalManifest when loader.RefreshModules() fails. RefreshModules downloads/updates the module manifest entries (the records describing locally-installed child modules). Failure means Terraform could not reconcile the manifest on disk with the registry, preventing the modules command from listing resolved versions.

Source

Thrown at internal/command/modules.go:138

	manifestWithRef := resolver.Resolve(config)

	// Render the new manifest with references
	return view.Display(*manifestWithRef)
}

// internalManifest will use the configuration loader to refresh and load the
// internal manifest.
func (c *ModulesCommand) internalManifest() (modsdir.Manifest, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	loader, err := c.initConfigLoader()
	if err != nil {
		diags = diags.Append(fmt.Errorf("Failed to initialize config loader: %w", err))
		return nil, diags
	}

	if err = loader.RefreshModules(); err != nil {
		diags = diags.Append(fmt.Errorf("Failed to refresh module manifest: %w", err))
		return nil, diags
	}

	return loader.ModuleManifest(), diags
}

const modulesCommandHelp = `
Usage: terraform [global options] modules [options]

  Prints out a list of all declared Terraform modules and their resolved versions
  in a Terraform working directory.

Options:

  -json               If specified, output declared Terraform modules and
                      their resolved versions in a machine-readable format.

  -var 'foo=bar'      Set a value for one of the input variables in the root

View on GitHub (pinned to c9def3e214)

Solutions

  1. Check network connectivity and registry/TF_TOKEN_* credentials for the module source hostname.
  2. Delete .terraform/modules and re-run 'terraform get' / 'terraform init' to rebuild the manifest.
  3. Ensure the working directory and TF_DATA_DIR are writable with adequate free disk space.
  4. Use -plugin-dir or vendored module paths to avoid registry access in air-gapped setups.

Example fix

// before: corrupt/partial module manifest
// after: rebuild module install
$ rm -rf .terraform/modules
$ terraform init
$ terraform modules
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: verify registry reachability and module manifest integrity
package main

func preflightModules(dataDir string) error {
	manifest := filepath.Join(dataDir, "modules", "modules.json")
	if info, err := os.Stat(manifest); err == nil && info.Size() == 0 {
		return fmt.Errorf("module manifest %s is empty; run 'terraform init'", manifest)
	}
	return nil
}

Prevention

When it happens

Trigger: Running 'terraform modules' when RefreshModules errors — typically a registry/network failure fetching module metadata, a corrupt modules manifest file (.terraform/modules/modules.json), or a filesystem write error updating the manifest.

Common situations: Air-gapped environment without registry access; a private module registry token expired or is misconfigured; the .terraform/modules directory was partially deleted; disk full preventing manifest write.

Related errors


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