What's Actually Happening

Uploads to AWS S3 fail with access denied or other errors. Files cannot be uploaded to buckets, multipart uploads fail, or timeouts occur during upload.

The Error You'll See

Access Denied:

```bash aws s3 cp file.txt s3://my-bucket/

upload failed: file.txt to s3://my-bucket/file.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied ```

Upload timeout:

bash
ConnectionError: Unable to connect to endpoint URL

Entity Too Large:

bash
An error occurred (EntityTooLarge) when calling the PutObject operation: Your proposed upload exceeds the maximum allowed size

Why This Happens

  1. 1.Insufficient permissions - IAM user lacks PutObject permission
  2. 2.Bucket policy - Bucket policy denying upload
  3. 3.Wrong region - Bucket in different region
  4. 4.Network issue - Connectivity problem to S3
  5. 5.Large file - File exceeds 5GB limit for single upload
  6. 6.KMS permissions - Missing key permissions for encryption
  7. 7.ACL issue - Object ACL not allowed

Step 1: Check IAM Permissions

```bash aws sts get-caller-identity

aws iam get-user

aws iam list-attached-user-policies --user-name myuser

aws iam get-policy-version --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --version-id v1

# Required permissions: # s3:PutObject # s3:GetObject # s3:ListBucket

# Check inline policy: aws iam get-user-policy --user-name myuser --policy-name policy-name ```

Step 2: Check Bucket Policy

```bash aws s3api get-bucket-policy --bucket my-bucket

aws s3api get-bucket-acl --bucket my-bucket

aws s3api get-public-access-block --bucket my-bucket

# Common bucket policy issues: # - Explicit deny # - Condition restrictions # - Principal mismatch ```

Step 3: Test S3 Access

```bash aws s3 ls s3://my-bucket/

aws s3api list-objects --bucket my-bucket

aws s3api get-object --bucket my-bucket --key file.txt /tmp/file.txt

# Test upload with AWS CLI: aws s3 cp test.txt s3://my-bucket/test.txt

# Test with AWS SDK: aws s3api put-object --bucket my-bucket --key test.txt --body test.txt ```

Step 4: Check Bucket Region

```bash aws s3api get-bucket-location --bucket my-bucket

aws configure get region

# If regions don't match: aws s3 cp file.txt s3://my-bucket/ --region us-east-1

aws s3api put-object --bucket my-bucket --key file.txt --body file.txt --region us-east-1 ```

Step 5: Handle Large Files

```bash # Files > 5GB need multipart upload:

# Use AWS CLI (auto multipart): aws s3 cp large-file.zip s3://my-bucket/large-file.zip

# Manual multipart: aws s3api create-multipart-upload --bucket my-bucket --key large-file.zip

aws s3api upload-part --bucket my-bucket --key large-file.zip --part-number 1 --upload-id id --body part1

aws s3api complete-multipart-upload --bucket my-bucket --key large-file.zip --upload-id id --multipart-upload file://parts.json ```

Step 6: Check KMS Permissions

```bash aws s3api get-bucket-encryption --bucket my-bucket

aws kms describe-key --key-id key-id

aws kms list-grants --key-id key-id

# Required KMS permissions: # kms:Encrypt # kms:Decrypt # kms:GenerateDataKey

# Check key policy: aws kms get-key-policy --key-id key-id --policy-name default ```

Step 7: Check Network Connectivity

```bash ping s3.amazonaws.com

curl -I https://s3.amazonaws.com

nslookup s3.amazonaws.com

# Check endpoint: aws s3 ls s3://my-bucket/ --endpoint-url https://s3.us-east-1.amazonaws.com

# For VPC endpoint: aws ec2 describe-vpc-endpoints --filters Name=service-name,Values=com.amazonaws.us-east-1.s3

# Test with verbose: aws s3 cp file.txt s3://my-bucket/ --debug ```

Step 8: Check Object Lock

```bash aws s3api get-object-lock-configuration --bucket my-bucket

# If object lock enabled, check retention: aws s3api head-object --bucket my-bucket --key file.txt

# Object lock prevents overwrites ```

Step 9: Check Request Rate

```bash # S3 has request rate limits: # 3500 PUT/COPY/POST/DELETE per second per prefix # 5500 GET/HEAD per second per prefix

# Check CloudWatch metrics: aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --metric-name PutRequests \ --dimensions Name=BucketName,Value=my-bucket \ --statistics Sum \ --period 60

# Distribute across prefixes if rate limited ```

Step 10: Monitor S3 Uploads

```bash # Enable S3 server access logging: aws s3api put-bucket-logging --bucket my-bucket --bucket-logging-status file://logging.json

# CloudWatch metrics: aws cloudwatch list-metrics --namespace AWS/S3

# Event notifications: aws s3api put-bucket-notification-configuration --bucket my-bucket --notification-configuration file://notification.json

# AWS Config for bucket compliance: aws configservice describe-compliance-by-resource --resource-types AWS::S3::Bucket ```

AWS S3 Upload Failed Checklist

CheckCommandExpected
IAM permissionsaws iam get-policys3:PutObject allowed
Bucket policyaws s3api get-bucket-policyNot denying
Bucket regionaws s3api get-bucket-locationCorrect region
File sizels -l file< 5GB for single upload
KMS accessaws kms describe-keyAccess granted
Networkping s3.amazonaws.comConnected

Verify the Fix

```bash aws sts get-caller-identity

aws s3 ls s3://my-bucket/

aws s3 cp test.txt s3://my-bucket/test.txt

aws s3api head-object --bucket my-bucket --key test.txt

aws s3 rm s3://my-bucket/test.txt

aws s3api get-bucket-encryption --bucket my-bucket ```

  • [Fix AWS S3 Access Denied Error](/articles/fix-aws-s3-access-denied-error)
  • [Fix AWS S3 Bucket Not Found](/articles/fix-aws-s3-bucket-not-found)
  • [Fix AWS Lambda Function Timeout](/articles/fix-aws-lambda-function-timeout)