hashicorp/terraform · critical

Error refreshing state

Error message

Error refreshing state: %s

What it means

Thrown when sMgr.RefreshState() fails during init after a state manager was successfully constructed. RefreshState contacts the backend to pull the latest state; failures are network/auth/I/O errors against the remote state store.

Solutions

  1. Verify the remote state object exists and is accessible from the configured backend.
  2. Check the lock table (DynamoDB) exists and is not held by another run.
  3. Retry on transient network errors; refresh credentials if expired.
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the state object exists before init refresh (S3 example).
func stateObjectExists(bucket, key string) bool {
    _, err := s3.HeadObject(bucket, key)
    return err == nil
}

Try / catch

// Retry transient refresh failures with backoff.
for i := 0; i < 3; i++ {
    if err := sMgr.RefreshState(); err == nil { break }
    time.Sleep(backoff(i))
}

Prevention

When it happens

Trigger: The state manager is built but refreshing state from the backend fails: S3 GET on the state key fails (404/403), DynamoDB lock acquisition fails, HTTP backend returns 5xx, or network timeout.

Common situations: State object deleted out-of-band; lock table missing; transient network error; credential expiry between StateMgr construction and refresh; concurrent state operation holding the lock.

Related errors


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

Appendix: source

Thrown at internal/command/init_run.go:328

	// on a previous run) we'll use the current state as a potential source
	// of provider dependencies.
	if back != nil {
		c.ignoreRemoteVersionConflict(back)
		workspace, err := c.Workspace()
		if err != nil {
			diags = diags.Append(fmt.Errorf("Error selecting workspace: %s", err))
			view.Diagnostics(diags)
			return 1
		}
		sMgr, sDiags := back.StateMgr(workspace)
		if sDiags.HasErrors() {
			diags = diags.Append(fmt.Errorf("Error loading state: %s", sDiags.Err()))
			view.Diagnostics(diags)
			return 1
		}

		if err := sMgr.RefreshState(); err != nil {
			diags = diags.Append(fmt.Errorf("Error refreshing state: %s", err))
			view.Diagnostics(diags)
			return 1
		}

		state = sMgr.State()
	}

	if initArgs.Get {
		modsOutput, modsAbort, modsDiags := c.getModules(ctx, path, initArgs.TestsDirectory, rootModEarly, initArgs.Upgrade, view, policyClient)
		diags = diags.Append(modsDiags)
		if modsAbort || modsDiags.HasErrors() {
			view.Diagnostics(diags)
			return 1
		}
		if modsOutput {
			// If we outputted information, then we need to output a newline
			// so that our success message is nicely spaced out from prior text.
			view.Spacer()

View on GitHub (pinned to d32a084675)