hashicorp/terraform · error

Failed to refresh state: %s

Error message

Failed to refresh state: %s

What it means

Thrown by `terraform state show` when stateMgr.RefreshState() fails after the state manager was obtained. RefreshState reads/locks the state from its backing store (local file, S3, cloud, etc.); failure means the state could not be read or locked. The %s is the underlying error (lock contention, IO error, network/auth failure).

Source

Thrown at internal/command/state_show.go:118

	schemas, diags := lr.Core.Schemas(lr.Config, lr.InputState)
	if diags.HasErrors() {
		return view.DisplayResourceInstanceState(jsonformat.State{}, diags)
	}

	// Get the state
	env, err := c.Workspace()
	if err != nil {
		diags = diags.Append(fmt.Sprintf("Error selecting workspace: %s\n", err))
		view.Diagnostics(diags)
		return 1
	}
	stateMgr, sDiags := b.StateMgr(env)
	if sDiags.HasErrors() {
		diags = diags.Append(fmt.Errorf(errStateLoadingState, sDiags.Err()))
		return view.DisplayResourceInstanceState(jsonformat.State{}, diags)
	}
	if err := stateMgr.RefreshState(); err != nil {
		diags = diags.Append(fmt.Errorf("Failed to refresh state: %s\n", err))
		return view.DisplayResourceInstanceState(jsonformat.State{}, diags)
	}

	state := stateMgr.State()
	if state == nil {
		diags = diags.Append(errors.New(errStateNotFound))
		return view.DisplayResourceInstanceState(jsonformat.State{}, diags)
	}

	is := state.ResourceInstance(addr)
	if !is.HasCurrent() {
		diags = diags.Append(errors.New(errNoInstanceFound))
		return view.DisplayResourceInstanceState(jsonformat.State{}, diags)
	}

	// check if the resource has a configured provider, otherwise this will use the default provider
	rs := state.Resource(addr.ContainingResource())
	absPc := addrs.AbsProviderConfig{

View on GitHub (pinned to c9def3e214)

Solutions

  1. Read the %s to identify lock vs IO vs auth.
  2. If locked by a dead process, `terraform force-unlock <LOCK_ID>` then retry.
  3. Verify backend connectivity/credentials (aws sts get-caller-identity, tf login) and re-run.
  4. Ensure only one Terraform process touches the workspace at a time.

Example fix

# before - state locked by a crashed run
terraform state show aws_instance.web
# Failed to refresh state: Failed to lock state: Lock Info...

# after
terraform force-unlock <LOCK_ID>
terraform state show aws_instance.web
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: confirm backend reachable and not obviously locked
// (backend-specific; verify credentials/endpoint before refresh)

Try / catch

// retry refresh on transient lock/network errors
for i := 0; i < 3; i++ {
    if err := stateMgr.RefreshState(); err != nil {
        if isLockBusy(err) || isTransient(err) {
            time.Sleep(backoff(i)); continue
        }
        return err
    }
    break
}

Prevention

When it happens

Trigger: Running `terraform state show` when the state manager exists but RefreshState errors: state lock held by another run, S3/cloud network or auth error mid-read, local terraform.tfstate unreadable, or HTTP backend returning an error.

Common situations: Another terraform apply/plan holding the state lock; expired cloud credentials; S3 bucket deleted or region mismatch; concurrent CI jobs on one workspace; local state file deleted between StateMgr() and RefreshState().

Related errors


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