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
- Verify the remote state object exists and is accessible from the configured backend.
- Check the lock table (DynamoDB) exists and is not held by another run.
- 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
- Verify the state object exists and is accessible.
- Ensure the lock table exists and is not held by another run.
- Retry transient network errors; refresh credentials if expired.
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
- Error loading state
- Error selecting workspace
- Failed to load state
- Failed to load state
- backendDiags.Err()
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)