How to fix Error: Failed to refresh state in Terraform

TerraformINTERMEDIATEHIGHUpdated Dec 30, 2025ยท 157 views

State refresh failures occur when Terraform can't synchronize with remote infrastructure due to state locks, connectivity issues, or resource changes. This guide covers diagnosis and recovery strategies for different root causes.

Quick fix

Fixes Error: Failed to refresh state

terraform state list
  1. Check for active state locks
  2. Verify backend connectivity and credentials
  3. Force unlock if state lock is stale
  4. Use refresh-only mode to diagnose issues
terraform โ€” error
terraform state list
Error: Failed to refresh state

What this error means

The "Failed to refresh state" error occurs when Terraform attempts to synchronize its state file with the actual state of your infrastructure but encounters an error in the process. Terraform refreshes state during plan and apply operations to ensure it has accurate information about what resources currently exist. This error can stem from several distinct issues: remote state backend problems (S3, Azure, Terraform Cloud), active state locks from incomplete operations, credential or authentication failures, network connectivity issues, or resources that were deleted or modified outside of Terraform. Unlike some transient failures, a refresh failure indicates a deeper problem that must be resolved before Terraform can proceed safely.

Typical symptoms

  • terraform plan or terraform apply commands fail immediately with "Failed to refresh state"
  • Operations hang or timeout while in the "Refreshing state" phase
  • Error messages reference S3, Azure Storage, DynamoDB, or other backend services
  • State lock timeout errors appear after waiting (with -lock-timeout flag)
  • No changes can be applied to infrastructure until state refresh succeeds

Common causes

  1. An active state lock from a previous incomplete or crashed Terraform operation is preventing access
  2. Remote state backend (S3, Azure Blob, Terraform Cloud) is unreachable or has connectivity issues
  3. Credentials or authentication tokens for the state backend have expired, are invalid, or lack required permissions
  4. Resources referenced in state no longer exist in the cloud provider (deleted manually or via other tools)
  5. Network timeouts or temporary backend outages during state fetch
  6. Misconfigured backend settings or S3/Azure eventual consistency delays

How to fix "Error: Failed to refresh state"

1Check for active state locks

First, determine if an active state lock is blocking operations. Use:

bash
terraform state list

If this command also fails with a lock error, you have a stale lock. List state locks in your backend:

For S3 backend with DynamoDB locking:

bash
aws dynamodb scan --table-name terraform-lock

For Azure Blob Storage:
Log into the Azure Portal, navigate to the Storage Account and Blob Container containing your state, and check the blob's properties for an active lease.

If you confirm a stale lock, proceed to Step 3. If no lock exists, move to Step 2.

2Verify backend connectivity and credentials

Ensure your backend credentials and connectivity are correct before attempting recovery.

For S3 backend:

bash
aws s3 ls s3://your-bucket/path/to/terraform.tfstate

For Azure Blob Storage:

bash
az storage blob exists --account-name youraccount --container-name yourcontainer --name terraform.tfstate

For Terraform Cloud:

bash
curl -H "Authorization: Bearer $TFE_TOKEN" \
  https://app.terraform.io/api/v2/state-versions

If connectivity fails, verify:
- AWS credentials are set (check aws sts get-caller-identity)
- Azure credentials are set (az account show)
- Terraform Cloud API token is valid (echo $TFE_TOKEN)
- Network allows outbound HTTPS connections
- Backend configuration in Terraform code is correct

3Force unlock if state lock is stale

If Step 1 confirmed a stale lock and Step 2 confirmed backend connectivity, unlock the state:

bash
terraform force-unlock <LOCK_ID>

Replace <LOCK_ID> with the lock ID from the state lock table (from Step 1).

For S3/DynamoDB:

bash
# Get the lock ID from DynamoDB
LOCK_ID=$(aws dynamodb scan --table-name terraform-lock \
  --query 'Items[0].ID.S' --output text)

terraform force-unlock $LOCK_ID

For Azure:
In the Azure Portal, navigate to the blob properties and use the "Break lease" button to release the lock.

After unlocking, attempt the operation again:

bash
terraform refresh
4Use refresh-only mode to diagnose issues

Once basic connectivity is restored, use refresh-only mode to identify what state differences exist without applying changes:

bash
terraform plan -refresh-only

This command will:
- Attempt to fetch current state
- Compare with your Terraform code
- Show what has changed in your infrastructure
- NOT apply any changes

Review the output carefully. If resources appear as destroyed that shouldn't be, this indicates resources were deleted outside Terraform (see Step 5).

If the plan succeeds, apply the refresh to update your local state:

bash
terraform apply -refresh-only
5Resolve resource deletions and rebuild state

If refresh-only mode shows resources that no longer exist in the cloud (marked for removal), you have two options:

Option A: Remove them from state (if deletion was intentional):

bash
terraform state rm 'aws_instance.example'

This removes the resource from Terraform's tracking without destroying it in the cloud.

Option B: Import the resource back (if it still exists but state is confused):

bash
terraform import aws_instance.example i-1234567890abcdef0

Option C: Restore the resource in the cloud (if it was deleted but should exist):
Manually recreate the resource using the cloud provider's console or CLI, then:

bash
terraform import <resource_type>.<name> <resource_id>

After state corrections, try the refresh again:

bash
terraform refresh
6Retry with timeout and exponential backoff

If the issue is temporary (backend slowness, eventual consistency in S3), use the -lock-timeout flag to give Terraform more time:

bash
terraform plan -lock-timeout=10m

For operations that consistently timeout, increase the timeout:

bash
terraform apply -lock-timeout=20m

Wait 1-2 minutes if using S3 backend (S3 eventual consistency), then retry:

bash
sleep 120
terraform plan

If problems persist after these steps, escalate to backend service support (HashiCorp Terraform Cloud, AWS, Azure, etc.) with the full error logs:

bash
TF_LOG=DEBUG terraform plan 2>&1 | tee terraform-debug.log

Advanced notes

State Refresh and Eventual Consistency:
When using S3 as a backend, AWS eventual consistency can cause temporary "state data in S3 does not have expected content" errors. If this occurs, wait 1-2 minutes and retry.

S3 State Lock Timeout Bug:
In some Terraform versions, if a lock timeout expires before acquiring the lock, Terraform may not retry properly if another process releases the lock during the wait. Force unlock and retry manually if this occurs.

Azure Lease Expiration:
Azure Blob Storage uses 60-second leases for state locking. If a Terraform process crashes, the lease automatically expires within 60 seconds. Manual intervention is only needed for process hangs beyond 60 seconds.

Preventing Future Lock Issues:
Use CI/CD pipeline mechanisms to prevent concurrent Terraform runs:
- GitLab: Use resource locks in pipelines
- GitHub Actions: Use concurrency groups
- Jenkins: Use lock mechanisms
- Terraform Cloud: Enforces mutual exclusion automatically

Disabling Locks (Not Recommended):
Use terraform plan -lock=false only for inspection operations (never with apply) if locks are permanently stuck. This is dangerous and should only be used as a last resort after confirming with your team that no other operations are running.

Frequently asked questions

What does "Error: Failed to refresh state" mean?
The "Failed to refresh state" error occurs when Terraform attempts to synchronize its state file with the actual state of your infrastructure but encounters an error in the process. Terraform refreshes state during plan and apply operations to ensure it has accurate information about what resources currently exist. This error can stem from several distinct issues: remote state backend problems (S3, Azure, Terraform Cloud), active state locks from incomplete operations, credential or authentication failures, network connectivity issues, or resources that were deleted or modified outside of Terraform.
How do I fix "Error: Failed to refresh state"?
State refresh failures occur when Terraform can't synchronize with remote infrastructure due to state locks, connectivity issues, or resource changes. This guide covers diagnosis and recovery strategies for different root causes.
What causes "Error: Failed to refresh state"?
An active state lock from a previous incomplete or crashed Terraform operation is preventing access Remote state backend (S3, Azure Blob, Terraform Cloud) is unreachable or has connectivity issues Credentials or authentication tokens for the state backend have expired, are invalid, or lack required permissions
Is the "Error: Failed to refresh state" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading