TerraformPilot

DevOps

Fix Terraform Error - Error Putting S3 Policy - MalformedPolicy

How to fix MalformedPolicy errors when applying S3 bucket policies in Terraform. Debug JSON syntax, ARN format, and principal issues.

LLuca Berton1 min read

The Error

#
Error putting S3 policy: MalformedPolicy: Invalid principal in policy

What Causes This

#

The S3 bucket policy has invalid JSON, incorrect ARN format, or references a principal that doesn't exist. This also happens when the policy is too large (20KB limit) or has conflicting statements.

How to Fix It

#

Solution 1: Use jsonencode Instead of Heredoc

#
# BAD — heredoc is error-prone
resource "aws_s3_bucket_policy" "public" {
  bucket = aws_s3_bucket.web.id
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}
EOF
}
 
# GOOD — jsonencode catches errors at plan time
resource "aws_s3_bucket_policy" "public" {
  bucket = aws_s3_bucket.web.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "PublicRead"
      Effect    = "Allow"
      Principal = "*"
      Action    = "s3:GetObject"
      Resource  = "${aws_s3_bucket.web.arn}/*"
    }]
  })
}

Solution 2: CloudFront OAC Policy

#
resource "aws_s3_bucket_policy" "cdn" {
  bucket = aws_s3_bucket.web.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "AllowCloudFront"
      Effect    = "Allow"
      Principal = {
        Service = "cloudfront.amazonaws.com"
      }
      Action    = "s3:GetObject"
      Resource  = "${aws_s3_bucket.web.arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.cdn.arn
        }
      }
    }]
  })
}

Solution 3: Validate with AWS CLI

#
# Test the policy before applying
aws s3api put-bucket-policy \
  --bucket my-bucket \
  --policy file://policy.json \
  --dry-run  # Not supported, but you can validate the JSON
  
# Check existing policy
aws s3api get-bucket-policy --bucket my-bucket | python3 -m json.tool

Prevention Tips

#
  1. Pin provider versions — avoid surprise breaking changes
  2. Use CI/CD — catch errors before they hit production
  3. Test with terraform plan — always review before applying
  4. Keep Terraform updated — newer versions have better error messages
  5. Use terraform validate — catches syntax errors early

Hands-On Courses

#

Learn to avoid these errors with interactive, project-based courses:

#

Conclusion

#

Related: Fix the Terraform inconsistent dependency lock file error — quick fix for this common issue.

This error is common and fixable. Follow the solutions above, and check our Terraform course for hands-on training that covers real-world troubleshooting scenarios.

#Terraform#Troubleshooting#DevOps#Error Fix#Infrastructure as Code

Share this article