How to fix Error: Failed to write state in Terraform

TerraformINTERMEDIATECRITICALUpdated Dec 30, 2025· 197 views

Terraform state write failures occur when Terraform cannot persist state changes to your backend storage due to permission issues, backend misconfiguration, or serial number conflicts. This prevents infrastructure changes from being recorded and can leave your state in an inconsistent state.

Quick fix

Fixes Error: Failed to write state

ls -la errored.tfstate
cat errored.tfstate | jq . | head -50
  1. Verify the errored.tfstate file exists and check its contents
  2. Identify the specific backend error in terraform logs
  3. For S3 backends, verify IAM permissions on bucket and DynamoDB lock table
  4. For Azure backends, verify storage account credentials and permissions
terraform — error
ls -la errored.tfstate
cat errored.tfstate | jq . | head -50
Error: Failed to write state

What this error means

After Terraform creates or modifies infrastructure, it must write the updated state file back to its configured backend (local filesystem, S3, Azure Storage, Terraform Cloud, etc.). A "Failed to write state" error means this write operation failed. Terraform will save the state to an "errored.tfstate" file for recovery, but resources remain created in your cloud provider while state is out of sync. This is dangerous because Terraform loses track of what infrastructure exists, potentially leading to orphaned resources or duplicate creation attempts.

Typical symptoms

  • terraform apply fails after resource creation with "Error: Failed to write state"
  • errored.tfstate file appears in your working directory after failed operation
  • Resources appear created in AWS/Azure/GCP but terraform state doesn't reflect them
  • Subsequent terraform commands fail with state inconsistency warnings
  • Backend API returns permission denied or access errors
  • CI/CD pipelines fail after infrastructure changes are partially applied
  • State file shows older resource versions than what exists in your cloud

Common causes

  1. S3 backend missing PutObject or ListBucket IAM permissions on bucket or bucket/* resources
  2. AWS credentials expired, revoked, or no longer valid
  3. Azure Storage account or container access credentials are incorrect or expired
  4. Insufficient permissions in Terraform Cloud workspace (not admin/owner)
  5. Backend configuration points to wrong bucket, container, or path
  6. State file serial number conflict when manually editing state
  7. DynamoDB lock table does not have CreateItem/PutItem permissions for S3 backends
  8. Network connectivity issues preventing communication with remote backend
  9. Disk full on local backend or remote backend storage capacity exceeded
  10. Locked state file preventing writes (held by another operation or corrupted lock)

How to fix "Error: Failed to write state"

1Verify the errored.tfstate file exists and check its contents

When Terraform fails to write state, it saves the attempted state to errored.tfstate in your working directory:

bash
ls -la errored.tfstate
cat errored.tfstate | jq . | head -50

This file contains the infrastructure changes Terraform was trying to persist. Keep this file safe—it's your recovery tool. Do NOT delete it yet.

2Identify the specific backend error in terraform logs

Re-run the failed terraform command with debug logging to see the exact backend error:

bash
TF_LOG=DEBUG terraform apply -out=tfplan 2>&1 | tail -100

Common errors to look for:
- "AccessDenied: Access Denied" → IAM permission issue
- "invalid character 'R' looking for beginning of value" → Backend returned invalid JSON
- "cannot serialize resource instance" → State corruption or provider issue
- "Error acquiring the state lock" → State is locked by another operation

Note the exact error message—it tells you whether the issue is permissions, connectivity, or state format.

3For S3 backends, verify IAM permissions on bucket and DynamoDB lock table

S3 backend failures are usually permission-related. Check your AWS credentials:

bash
aws sts get-caller-identity

Verify the returned user/role has these permissions:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-terraform-bucket",
        "arn:aws:s3:::my-terraform-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:DeleteItem",
        "dynamodb:DescribeTable"
      ],
      "Resource": "arn:aws:dynamodb:*:ACCOUNT_ID:table/terraform-state-lock"
    }
  ]
}

If permissions are missing, contact your AWS admin to update the IAM policy. Then retry:

bash
terraform apply -out=tfplan
4For Azure backends, verify storage account credentials and permissions

Azure backend errors usually indicate authentication or access issues:

bash
az account show
az storage account show --name mystorageaccount

Verify your storage account key or SAS token is current:

bash
az storage account keys list --name mystorageaccount --resource-group myresourcegroup

If keys are old, rotate them:

bash
az storage account keys renew --name mystorageaccount --resource-group myresourcegroup --key primary

Update your .env file or terraform backend config with the new key, then retry:

bash
terraform init
terraform apply -out=tfplan
5For Terraform Cloud, verify workspace permissions and API token

Terraform Cloud write failures happen when your user lacks workspace permissions:

bash
terraform login

When prompted, generate a new API token at https://app.terraform.io/app/settings/tokens

Verify your user has proper permissions for the workspace:
- Go to your workspace in Terraform Cloud
- Click Settings > Team access
- Ensure your team has "Manage all workspaces" or "Write" permission

Also verify the workspace exists and you're targeting the right organization:

bash
terraform workspace list
terraform workspace select production
6Recover state by pushing errored.tfstate back to backend

Once you've fixed the underlying issue (permissions, credentials, connectivity), push the errored state to the backend:

bash
terraform state push errored.tfstate

Terraform will verify the serial number matches and push the state. If you get a serial number conflict error:

bash
jq .serial errored.tfstate
jq .serial terraform.tfstate

If errored.tfstate has a lower serial, manually increment it:

bash
jq '.serial += 1' errored.tfstate > errored.tfstate.new && mv errored.tfstate.new errored.tfstate
terraform state push errored.tfstate

After successful push, verify the state is now consistent:

bash
terraform state list
terraform plan  # Should show no changes
7If serial number conflict persists, manually resolve state serial version

State serial number conflicts occur when your local state is older than the remote state. This happens if someone else applied changes while you had state write failures.

Check the conflict:

bash
terraform state pull > remote.tfstate
jq .serial remote.tfstate
jq .serial errored.tfstate

If errored.tfstate serial is lower, update it to be higher:

bash
REMOTE_SERIAL=$(jq .serial remote.tfstate)
NEW_SERIAL=$((REMOTE_SERIAL + 1))
jq --arg serial "$NEW_SERIAL" '.serial = ($serial | tonumber)' errored.tfstate > errored.tfstate.new
mv errored.tfstate.new errored.tfstate
terraform state push errored.tfstate

This tells Terraform that your local state is the newer version, allowing the push to succeed.

8Verify resource consistency and reconcile any orphaned infrastructure

After recovering state, verify your infrastructure matches what Terraform knows about:

bash
terraform plan

If plan shows:
- No changes → State is now consistent, you're done
- Changes needed → Terraform found drift between state and real infrastructure
- Resources to destroy → Possible zombie resources created during failed operation

For zombie resources (created but not in state), decide whether to:

Option A: Import them into state

bash
terraform import aws_instance.web i-1234567890abcdef0

Option B: Destroy them manually (in AWS/Azure/GCP console) and document the orphan

Option C: Use terraform apply to recreate/update resources matching the recovered state

Once plan shows no unexpected changes, apply the fix:

bash
terraform apply

Advanced notes

State write failures are arguably the scariest Terraform errors because they leave infrastructure untracked. Prevention is critical:

Pre-flight permission checks: Before running apply, test backend connectivity:

bash
terraform init -upgrade
terraform validate
terraform refresh  # Syncs state with real infrastructure

State snapshots: Regularly back up your state file (especially before major changes):

bash
terraform state pull > state-backup-$(date +%Y%m%d-%H%M%S).json

Lock tables for S3: If using S3 backends without a DynamoDB lock table, add one:

hcl
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-state-lock"
  }
}

CI/CD safety: Never run terraform apply without protecting against concurrent operations. Use GitHub Actions concurrency, GitLab resource_groups, or Jenkins mutex locks.

Manual state edits (rare): If you must manually edit state files, always work on a copy and increment the serial number. Better yet, use terraform state commands instead of editing JSON directly.

Frequently asked questions

What does "Error: Failed to write state" mean?
). A "Failed to write state" error means this write operation failed. tfstate" file for recovery, but resources remain created in your cloud provider while state is out of sync.
How do I fix "Error: Failed to write state"?
Terraform state write failures occur when Terraform cannot persist state changes to your backend storage due to permission issues, backend misconfiguration, or serial number conflicts. This prevents infrastructure changes from being recorded and can leave your state in an inconsistent state.
What causes "Error: Failed to write state"?
S3 backend missing PutObject or ListBucket IAM permissions on bucket or bucket/* resources AWS credentials expired, revoked, or no longer valid Azure Storage account or container access credentials are incorrect or expired
Is the "Error: Failed to write state" error serious?
Yes. This is a critical-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading