Problem: S3 File Upload is Successful but Returns 403 Forbidden on Access
Problem: S3 File Upload is Successful but Returns 403 Forbidden on Access
Bash
$ aws s3 cp myfile.txt s3://my-private-bucket/
upload: ./myfile.txt to s3://my-private-bucket/myfile.txt
$ aws s3 ls s3://my-private-bucket/
2025-02-09 10:05:32 102400 myfile.txt
# Try to access the file via URL
$ curl -I https://my-private-bucket.s3.amazonaws.com/myfile.txt
HTTP/1.1 403 Forbidden
x-amz-request-id: 123456789ABCDEF
x-amz-id-2: abcdef1234567890abcdef1234567890abcdef1234567890abcdef
Content-Type: application/xml
Issue:
Even though the file was successfully uploaded, trying to access it via a web browser or curl returns 403 Forbidden. This usually happens because:
- Bucket Public Access Block settings – The bucket has public access completely disabled.
- Object ACL is private – The file is uploaded without public-read permissions.
- Missing or restrictive bucket policy – The bucket policy does not allow public access.
Fix: Adjust ACLs and Bucket Policy to Allow Public Access
Bash
# Step 1: Check if public access is blocked at the bucket level
$ aws s3api get-public-access-block --bucket my-private-bucket
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true, # TRUE = Blocks public access via ACLs
"IgnorePublicAcls": true, # TRUE = Ignores any existing public ACLs
"BlockPublicPolicy": true, # TRUE = Prevents public bucket policies
"RestrictPublicBuckets": true # TRUE = Completely blocks all public access
}
}
# Explanation:
# If ANY of these values are "true," then the bucket will ignore ACLs and
# policies that allow public access. This is why even correctly
# configured permissions might still result in "403 Forbidden" errors.
# Step 2: Remove public access block settings if public access is needed
$ aws s3api delete-public-access-block --bucket my-private-bucket
# Step 3: Set the object ACL to allow public read
$ aws s3api put-object-acl --bucket my-private-bucket --key myfile.txt --acl public-read
# Step 4: Verify the ACL is now set to public-read
$ aws s3api get-object-acl --bucket my-private-bucket --key myfile.txt
{
"Owner": { "DisplayName": "aws-user", "ID": "abcdef1234567890" },
"Grants": [
{
"Grantee": {
"Type": "CanonicalUser",
"ID": "abcdef1234567890"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
},
"Permission": "READ"
}
]
}
# Step 5: Add a bucket policy to allow public reads (optional)
$ aws s3api put-bucket-policy --bucket my-private-bucket --policy '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-private-bucket/*"
}
]
}'
# Step 6: Verify public access with curl
$ curl -I https://my-private-bucket.s3.amazonaws.com/myfile.txt
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 102400
Need AWS Expertise?
If you're looking for guidance on AWS challenges or want to collaborate, feel free to reach out! We'd love to help you tackle your AWS projects. 🚀
Email us at: info@pacificw.com
Image: Gemini
Comments
Post a Comment