hashicorp/terraform · error

failed to read dependency lock file

Error message

failed to read dependency lock file: %s

What it means

Meta.ProviderFactories calls lockedDependencies() to read the dependency lock file (.terraform.lock.hcl). If that returns diagnostics with errors, the lock file could not be parsed or loaded, so provider factories cannot be constructed safely and the whole error is wrapped with this message. This is a hard gate: without a readable lock file Terraform refuses to build provider factories from locks.

Solutions

  1. Run terraform init -upgrade to regenerate a valid .terraform.lock.hcl from the current required_providers block.
  2. Inspect the embedded diagnostics (%s expands to diags.Err()) for the precise HCL parse location and fix that line.
  3. If the lock file has merge conflicts, resolve the conflict markers then re-run terraform init.
  4. As a last resort, back up and remove .terraform.lock.hcl, then terraform init to rebuild it; commit the regenerated file.

Example fix

# before: corrupt lock file causes 'failed to read dependency lock file'
# after: regenerate
rm .terraform.lock.hcl
terraform init -upgrade
git add .terraform.lock.hcl && git commit -m "chore: regenerate dependency lock file"
Defensive patterns

Strategy: validation

Validate before calling

// Validate the lock file parses before relying on ProviderFactories.
_, diags := m.lockedDependencies()
if diags.HasErrors() {
    return fmt.Errorf("lock file unreadable, run 'terraform init -upgrade': %s", diags.Err())
}

Prevention

When it happens

Trigger: Meta.ProviderFactories() is invoked (transitively by most commands that need providers); m.lockedDependencies() returns diags where diags.HasErrors() is true, typically because the lock file is syntactically invalid, truncated, or missing required checksum/version blocks for a declared provider.

Common situations: Hand-edited or partially-merged .terraform.lock.hcl with HCL syntax errors; lock file corrupted by a git merge conflict left unresolved; lock file from an incompatible Terraform version; lock file deleted but referenced; non-UTF8 bytes written by a broken editor.

Related errors


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

Appendix: source

Thrown at internal/command/meta_providers.go:314

		),
	}
}

// ProviderFactories uses the selections made previously by an installer in
// the local cache directory (m.providerLocalCacheDir) to produce a map
// of provider addresses to factory functions to create instances of
// those providers.
//
// ProviderFactories will return an error if the installer's selections cannot
// be honored with what is currently in the cache, such as if a selected
// package has been removed from the cache or if the contents of a selected
// package have been modified outside of the installer. If it returns an error,
// the returned map may be incomplete or invalid, but will be as complete
// as possible given the cause of the error.
func (m *Meta) ProviderFactories() (map[addrs.Provider]providers.Factory, error) {
	locks, diags := m.lockedDependencies()
	if diags.HasErrors() {
		return nil, fmt.Errorf("failed to read dependency lock file: %s", diags.Err())
	}

	return m.providerFactoriesFromLocks(locks)
}

// ProviderFactoriesFromLocks receives in memory locks and uses them to produce a map
// of provider addresses to factory functions to create instances of
// those providers.
//
// ProviderFactoriesFromLocks should only be used if the calling code relies on locks
// that have not yet been persisted to a dependency lock file on disk. Realistically, this
// means only code in the init command should use this method.
func (m *Meta) ProviderFactoriesFromLocks(configLocks *depsfile.Locks) (map[addrs.Provider]providers.Factory, error) {
	// Ensure overrides and unmanaged providers are reflected in the returned list of factories,
	// while avoiding mutating the in-memory
	locks := m.annotateDependencyLocksWithOverrides(configLocks.DeepCopy())

	return m.providerFactoriesFromLocks(locks)

View on GitHub (pinned to d32a084675)