AWS
Amazon S3
File Serving Issues
Cloud Storage
Troubleshooting

Amazon S3 is not serving files correctly

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When S3 is "not serving files correctly," the real problem is usually not S3 availability. It is usually one of a few specific issues: the wrong endpoint, missing permissions, bad object metadata, or stale CDN caching in front of the bucket.

The fastest way to debug it is to start from the HTTP response you actually get. A 403, 404, 301, or broken download behavior each point to different causes.

Start with the Status Code

A few common patterns are:

  • '403 Forbidden: permissions, Block Public Access, or KMS-related access problems'
  • '404 Not Found: wrong object key or wrong bucket path'
  • '301 or redirect errors: wrong region or wrong endpoint style'
  • file downloads with wrong behavior: incorrect Content-Type or Content-Disposition

That means you should inspect the object and bucket configuration before changing application code.

Check the Object Directly

The AWS CLI makes it easy to inspect the exact metadata S3 is serving:

bash
aws s3api head-object \
  --bucket my-site-assets \
  --key images/logo.png

This shows fields such as ContentType, ContentLength, CacheControl, and sometimes ContentEncoding. If the browser is downloading an image instead of rendering it, or showing raw text with the wrong encoding, bad metadata is often the reason.

For example, serving a CSS file as binary/octet-stream instead of text/css can confuse browsers and proxies.

Verify Permissions and Public Access Rules

If the object exists but requests return 403, inspect the bucket policy and Block Public Access settings. A public website bucket usually needs s3:GetObject permission on the object ARN path:

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Principal": "*",
7      "Action": "s3:GetObject",
8      "Resource": "arn:aws:s3:::my-site-assets/*"
9    }
10  ]
11}

That policy alone is not enough if Block Public Access is still enabled for the bucket or the account. In that case, S3 will continue to deny public reads.

Use the Correct Endpoint Type

S3 has more than one way to reach the same bucket:

  • the REST endpoint for normal object access
  • the static website endpoint for website hosting behavior

If you need index documents and error documents, use the static website hosting endpoint. If you use the normal REST endpoint instead, website-style behavior such as automatic index resolution does not happen.

Region also matters. A request sent to the wrong regional endpoint may redirect or fail in ways that look unrelated at first.

CloudFront Can Make the Problem Look Like S3

Many applications serve S3 content through CloudFront. In that setup, the file may already be fixed in S3 while CloudFront continues serving the old version from cache.

When that happens:

  • verify the object in S3 directly
  • compare the headers returned by S3 and CloudFront
  • invalidate the CloudFront cache if needed

If S3 is correct and CloudFront is stale, changing the bucket again will not help.

Set Metadata Correctly When Uploading

A reliable way to avoid serving issues is to set the right metadata at upload time:

bash
aws s3 cp app.js s3://my-site-assets/app.js \
  --content-type application/javascript \
  --cache-control "public,max-age=31536000"

For assets, correct metadata is part of the deploy, not an afterthought.

Common Pitfalls

  • Debugging S3 without first checking the actual HTTP status code.
  • Forgetting that Block Public Access can override a seemingly correct bucket policy.
  • Using the REST endpoint when you meant to use the static website endpoint.
  • Uploading files with the wrong Content-Type and then blaming the browser.
  • Fixing the object in S3 while a CDN still serves the stale cached version.

Summary

  • Most S3 serving problems come from permissions, endpoints, metadata, or caching rather than S3 itself.
  • Start with the HTTP status code because it narrows the problem quickly.
  • Use head-object to inspect what S3 is actually serving.
  • Check bucket policy and Block Public Access together, not in isolation.
  • If CloudFront is in front of S3, verify whether the issue is really cache-related.

Course illustration
Course illustration

All Rights Reserved.