Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AWS with AI By James Joyner IV · · 8 min read Last reviewed Jul 2026

AWS Error: '403 when calling the HeadObject operation: Forbidden' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix the S3 '(403) when calling the HeadObject operation: Forbidden' from aws s3 cp/sync: missing GetObject, KMS decrypt, or a bucket-policy deny.

  • #aws
  • #cloud
  • #troubleshooting
  • #errors
  • #s3
Free toolkit

Stuck on this AWS with AI error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

aws s3 cp/sync issue a HeadObject request before downloading an object. When your principal is allowed to reach the bucket but not to read that specific object, S3 answers the head request with HTTP 403 Forbidden. Because HeadObject returns no error body, the CLI surfaces a bare 403 ... Forbidden with no detail — which makes this one of the more confusing S3 errors to triage.

You will see it from the CLI:

fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

It occurs when the object is readable in principle but blocked by a missing s3:GetObject, a denied KMS key, a bucket-policy Deny, cross-account object ownership, or (deceptively) a wrong key with no ListBucket permission to distinguish 404 from 403.

Symptoms

  • aws s3 cp s3://bucket/key . or aws s3 sync fails with (403) ... HeadObject ... Forbidden.
  • aws s3 ls s3://bucket/ may succeed while downloading a specific object fails (or vice versa).
  • The same object downloads fine for the account root or the bucket owner but not for your role.
  • It appears only for KMS-encrypted objects, or only for objects uploaded by another account.
aws s3 cp s3://app-artifacts-REDACTED/builds/app.tar.gz .
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

Common Root Causes

1. Missing s3:GetObject on the object

Your identity/bucket policy grants ListBucket but not GetObject for that key/prefix.

2. No permission on the KMS key (SSE-KMS)

The object is encrypted with a KMS key your principal can’t kms:Decrypt, so the read is denied even with GetObject.

3. A bucket-policy or SCP explicit Deny

A Deny (e.g. requiring a VPC endpoint, TLS, or specific principal) overrides your allow.

4. Cross-account object ownership / ACLs

The object was uploaded by another account and, without Bucket Owner Enforced / correct ACLs, the bucket owner (you) can’t read it.

5. A wrong key masquerading as 403

Without s3:ListBucket, S3 returns 403 instead of 404 for a non-existent key — so a typo’d path looks like a permissions problem.

How to diagnose

Step 1: Confirm your identity and target

aws sts get-caller-identity --query Arn --output text
aws s3api head-object --bucket app-artifacts-REDACTED --key builds/app.tar.gz

The raw head-object returns the same 403; if ListBucket is present, list to confirm the key exists:

aws s3api list-objects-v2 --bucket app-artifacts-REDACTED --prefix builds/app.tar.gz \
  --query 'Contents[].Key' --output text

Empty output = wrong key (a 404 wearing a 403 mask); a hit = genuine permission issue.

Step 2: Check the bucket policy for denies and KMS

aws s3api get-bucket-policy --bucket app-artifacts-REDACTED --query Policy --output text | python3 -m json.tool
aws s3api head-object --bucket app-artifacts-REDACTED --key builds/app.tar.gz \
  --query '[ServerSideEncryption,SSEKMSKeyId]' 2>/dev/null

Step 3: Simulate the object read

aws iam simulate-principal-policy \
  --policy-source-arn "$(aws sts get-caller-identity --query Arn --output text)" \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::app-artifacts-REDACTED/builds/app.tar.gz \
  --query 'EvaluationResults[].EvalDecision' --output text

Fixes

Grant s3:GetObject on the prefix

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::app-artifacts-REDACTED/builds/*"
}

Grant KMS decrypt for SSE-KMS objects

Add kms:Decrypt for the object’s key to your policy, and ensure the KMS key policy trusts your principal:

{ "Effect": "Allow", "Action": "kms:Decrypt", "Resource": "arn:aws:kms:us-east-1:111122223333:key/REDACTED" }

Remove or satisfy the bucket-policy Deny

If a Deny requires a VPC endpoint or TLS, access the bucket via the required path (through the endpoint / over HTTPS) rather than editing the guardrail away.

Fix cross-account ownership

Enable Bucket Owner Enforced (Object Ownership) so uploads land owned by the bucket owner, or have the uploader grant bucket-owner-full-control.

What to watch out for

  • HeadObject returns no error detail — always reproduce with s3api head-object and cross-check with list-objects-v2 to separate 403 from a hidden 404.
  • Add s3:ListBucket so missing keys return an honest 404 instead of a misleading 403.
  • SSE-KMS needs both s3:GetObject and kms:Decrypt, and the KMS key policy must also allow your principal.
  • An explicit Deny in the bucket policy or an SCP wins over any Allow — check for denies before adding more allows.
Free download · 368-page PDF

Fixed it? Get 500 AWS with AI & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.