Table of Contents

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

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.