Skip to main content
Fix Terraform Error - Provider Produced Inconsistent Result After Apply

Fix Terraform Error - Provider Produced Inconsistent Result After Apply

Key Takeaway

Fix 'provider produced inconsistent result' errors in Terraform. Handle API normalization, default values, computed fields, and provider bugs.

Table of Contents

Quick Answer

The cloud API returned a value different from what Terraform expected after applying. This is usually a provider bug (API normalizes values) or a computed attribute that changes server-side. Workaround with ignore_changes lifecycle or upgrade the provider.

The Error

Error: Provider produced inconsistent result after apply

When applying changes to aws_security_group.web, the provider
produced an unexpected new value for was present, but now absent.

What Causes This

1. API Normalization

The cloud API reformats your input. For example:

  • JSON policy gets reordered/whitespace-normalized
  • CIDR 10.0.0.0/16 becomes 10.0.0.0/16 (trailing zeros stripped)
  • Tags get lowercased or trimmed

2. Server-Side Defaults

The API adds fields you didn’t specify, and the provider doesn’t handle them correctly.

3. Provider Bug

The provider doesn’t properly reconcile what it sent vs. what the API returned.

4. Eventual Consistency

AWS services like IAM may take time to propagate; Terraform reads back stale data.

How to Fix It

Solution 1: Upgrade the Provider

terraform init -upgrade
terraform plan
# Many inconsistency bugs are fixed in newer provider versions

Solution 2: Use ignore_changes

resource "aws_security_group" "web" {
  name   = "web-sg"
  vpc_id = aws_vpc.main.id

  lifecycle {
    ignore_changes = [
      ingress,  # Ignore if API reorders ingress rules
      tags,     # Ignore if API normalizes tags
    ]
  }
}

Solution 3: Normalize JSON Inputs

# ❌ Raw JSON string — API may reorder keys
resource "aws_iam_role" "main" {
  assume_role_policy = <<-EOF
    {"Version":"2012-10-17","Statement":[...]}
  EOF
}

# ✅ Use jsonencode — canonical key ordering
resource "aws_iam_role" "main" {
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
    }]
  })
}

Solution 4: Apply Again

Sometimes the second apply succeeds because state now matches reality:

terraform apply  # May succeed on retry

Solution 5: Refresh State

terraform apply -refresh-only  # Sync state with actual cloud values
terraform plan                 # Check if issue is resolved

Common Resources with This Issue

ResourceCauseFix
aws_security_groupRule reorderingignore_changes = [ingress, egress]
aws_iam_rolePolicy JSON normalizationUse jsonencode()
aws_s3_bucketACL/CORS defaultsUpgrade provider
azurerm_*API returns extra fieldsUpgrade provider

Troubleshooting Checklist

  1. ✅ Is this a known provider bug? (Check GitHub issues)
  2. ✅ Are you on the latest provider version?
  3. ✅ Can you use jsonencode() for policy documents?
  4. ✅ Does ignore_changes work as a workaround?
  5. ✅ Does a second terraform apply succeed?

Conclusion

“Inconsistent result after apply” is usually a provider bug where the API normalizes values differently than expected. Upgrade the provider first, use jsonencode() for policies, and ignore_changes as a last resort. Report persistent issues on the provider’s GitHub.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.