hashicorp/terraform · critical

backendDiags.Err()

Error message

backendDiags.Err()

What it means

This panic fires in StateMeta when c.Backend(&BackendOpts{ForceLocal: true}) returns diagnostics with errors. The local backend is the built-in fallback that stores state on the local filesystem, so it must always be constructable — an error here means the local backend registry/construction is broken, not a user-config problem.

Source

Thrown at internal/command/state_meta.go:67

		// Check remote Terraform version is compatible
		remoteVersionDiags := c.remoteVersionCheck(b, workspace)
		c.showDiagnostics(remoteVersionDiags)
		if remoteVersionDiags.HasErrors() {
			return nil, fmt.Errorf("Error checking remote Terraform version")
		}

		// Get the state
		s, sDiags := b.StateMgr(workspace)
		if sDiags.HasErrors() {
			return nil, sDiags.Err()
		}

		// Get a local backend
		localRaw, backendDiags := c.Backend(&BackendOpts{ForceLocal: true})
		if backendDiags.HasErrors() {
			// This should never fail
			panic(backendDiags.Err())
		}
		localB := localRaw.(*backendLocal.Local)
		_, stateOutPath, _ = localB.StatePaths(workspace)
		if err != nil {
			return nil, err
		}

		realState = s
	}

	// We always backup state commands, so set the back if none was specified
	// (the default is "-", but some tests bypass the flag parsing).
	if backupPath == "-" || backupPath == "" {
		// Determine the backup path. stateOutPath is set to the resulting
		// file where state is written (cached in the case of remote state)
		backupPath = fmt.Sprintf(
			"%s.%d%s",
			stateOutPath,

View on GitHub (pinned to d32a084675)

Solutions

  1. Run `terraform version` and `terraform init` to confirm the binary is intact; if those also fail, reinstall the Terraform binary from an official release.
  2. Check the workspace: ensure the working directory is writable and the .terraform/ directory is not partially deleted; remove .terraform and re-run `terraform init`.
  3. If building Terraform from source, confirm the build is clean (`go build ./...`) and that backend/local is included.
  4. File a bug with the full stack trace if it reproduces on an official release — this path is documented as must-succeed.

Example fix

// before
localRaw, backendDiags := c.Backend(&BackendOpts{ForceLocal: true})
if backendDiags.HasErrors() { panic(backendDiags.Err()) }
// after — surface as a real diagnostic instead of crashing (for maintainers)
if backendDiags.HasErrors() {
  diags = diags.Append(tfdiags.Sourceless(tfdiags.Error,
    "Failed to initialize local backend",
    backendDiags.Err().Error()))
  return nil, diags
}
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on the local backend, probe it explicitly.
localRaw, diags := c.Backend(&BackendOpts{ForceLocal: true})
if diags.HasErrors() {
  return nil, fmt.Errorf("local backend unavailable: %w", diags.Err())
}

Type guard

// n/a

Prevention

When it happens

Trigger: Any state command (state list/show/mv/rm/push/pull) calling backendsAndState via StateMeta. Fires when the forced-local backend construction itself returns errors, e.g. the local backend schema fails to build, a required plugin for the 'local' backend is missing from the binary, or an internal init path throws.

Common situations: A broken Terraform build (local backend not compiled in), an internal refactor that broke backendLocal registration, or a corrupted/missing state directory that the local backend cannot initialize. Extremely rare in released binaries.

Related errors


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