IAM policy blocks Athena query access to S3 bucket: AccessDenied errors on analytics jobs

Users receive AccessDenied errors when running Athena queries against our analytics S3 bucket after we updated the IAM policy structure. The queries worked fine until we reorganized our S3 bucket policies and Athena execution roles last week.

Error from Athena console:


Access Denied (Service: Amazon S3; Status Code: 403)
at AthenaQuery.execute(line 89)

The S3 bucket policy references the correct Athena execution role ARN, and IAM role permissions include s3:GetObject and s3:ListBucket actions. We’ve verified the Athena execution role setup has the necessary trust relationship with Athena service principal. What’s the correct way to configure these three components together?

Yes, KMS key policy definitely needs the Athena execution role as a key user. I’ve seen this trip people up constantly. The role needs kms:Decrypt, kms:DescribeKey, and kms:GenerateDataKey. Also double-check that your bucket policy Resource uses correct wildcard syntax like arn:aws:s3:::bucket-name/path/* for objects.

Subfolder structure changes are often the culprit! Your bucket policy Resource ARN probably needs wildcards to match the new path structure. If you moved from flat structure to folders, the Resource might still point to the old paths. Also check if you’re using KMS encryption - that requires additional permissions in both the key policy and IAM role.

I had this exact issue last month. The problem was the bucket policy Resource ARN was too specific. When you have subfolders, you need both the folder path AND wildcard for objects. Also make sure your IAM role has permissions for the Athena results bucket - queries fail if they can’t write results even if they can read source data.

Here’s the complete solution addressing all three configuration areas:

S3 Bucket Policy Configuration: Your bucket policy needs two Resource statements - one for the bucket itself and one for objects with wildcard. Update to:

{
  "Resource": [
    "arn:aws:s3:::analytics-bucket",
    "arn:aws:s3:::analytics-bucket/*"
  ]
}

IAM Role Permissions: The Athena execution role needs permissions for both source and results buckets:

  • Source bucket: s3:GetObject, s3:ListBucket
  • Results bucket: s3:PutObject, s3:GetObject, s3:ListBucket
  • KMS key: kms:Decrypt, kms:DescribeKey, kms:GenerateDataKey

Add a statement for Athena results location:

{
  "Action": ["s3:PutObject", "s3:GetObject"],
  "Resource": "arn:aws:s3:::athena-results-bucket/*"
}

Athena Execution Role Setup: Verify the role trust policy allows Athena service:

{
  "Principal": {"Service": "athena.amazonaws.com"},
  "Action": "sts:AssumeRole"
}

For KMS-encrypted buckets, update the KMS key policy to include your execution role ARN as a key user. The key policy must explicitly grant kms:Decrypt and kms:GenerateDataKey to the role.

Common mistake: The bucket policy Principal should reference the role ARN, not the Athena service. The service principal goes in the role’s trust policy, not the bucket policy.

After making these changes, test with a simple SELECT query first. If it works, the configuration is correct. The 403 errors should resolve once all three components align properly with the wildcard paths and KMS permissions.

That’s helpful! I’ll check the results bucket permissions. We do use KMS encryption on the analytics bucket. The IAM role has kms:Decrypt but maybe the key policy needs updating too?

Check if your S3 bucket policy explicitly denies access for certain conditions that might be triggering. Also verify the Athena workgroup settings - sometimes the execution role specified at workgroup level overrides the one you think is being used. Can you share the bucket policy structure (sanitized)?