Skip to content

CloudFront with S3 Bucket Static Page - Consistent 503 LimitExceeded Errors

0

EDIT For future engineers, check out my other comment in this re:Post chat, the issue ended up being a burst limit with the number of simultaneous HTTP requests under the free-tier in CloudFront.

CloudFront Distribution Link:

https://d3n5jstxb8npc3.cloudfront.net/

S3 Bucket Static Webpage Link (Public):

https://mlem-website.s3.us-east-1.amazonaws.com/index.html - EDIT: Changed to private

Problem:

My CloudFront distribution fails to serve most content on my page. Some static content loads, but a large percentage of it fails consistently (mixed media such as .png, .svg, .js, etc).

In my developer console network tab, I can see the content is failing to load with a 503 - LimitExceeded error. This issue does not occur when accessing the webpage directly via the S3 static webpage.

I am currently on the CloudFront free tier, I am just testing this website at the moment, so it's just me. I would not expect CloudFront to fail with this simple static website.

Solutions Attempted

  • Created two distributions with CloudFront and used the default settings for a S3 public static website bucket to verify issue is persistent.
  • Cleared distribution cache (/*) on my distribution.
  • Forced my developer console to 'disable cache' so I can confirm the error is consistent on retry.
  • CloudFront monitoring shows the 500 status errors on my dashboard, but not other useful information was spotted.
  • My CloudFront distribution has 'GET', 'HEAD' enabled, its not set to compress objects automatically (although that didn't seem to change anything on testing). My Viewer Protocol Policy is set to 'Redirect HTTP to HTTPS'. Restrict Viewer Access is set to 'No'. My Cache Policy is currently set to 'CachingDisabled' (I previously had it set to the default of 'CachingOptimized' with no change). I have no Origin Request Policy and no Response Header. And I have no Function Associations.

Request

  • If anyone has any idea what to try, please let me know. I've contacted support but their auto-response system is requesting I make a re:Post message before I can have an AWS engineer look over the bug.
4 Answers
0

I cannot replicate your issue. You CloudFront link loads just fine with almost every elements with status code - 200. Enter image description here

EXPERT

answered 10 months ago

  • Coming back to the CloudFront distribution to test it this morning, and now everything loads. I'm curious what was going on yesterday, but at least it's behaving now.

  • CloudFront Distribution: https://d3n5jstxb8npc3.cloudfront.net/

    I'm now able to replicate the issue again, after calling a CloudFront distribution invalidation (/*). Same 503 LimitExceeded error appears across a myriad of asset loads. The errors seem to stick around for an indeterminate amount of time (at least 1-2 hours, yesterday I had to wait all night for the issue to clear)

    Right now I run a Github Action to copy my assets to my private S3 bucket and invalidate the CloudFront distribution whenever I update my main branch of my website repo. This seems to be a normal way of doing things, but this 503 CloudFront bug is actively blocking me from going live.

0

A consistent 503 LimitExceeded from CloudFront almost always points to throttling at the S3 origin rather than CloudFront itself. When CloudFront uses an S3 bucket configured as a static website endpoint (the one ending in s3-website-...amazonaws.com), it communicates through the public website layer, which has much lower request concurrency limits. It’s better to set your CloudFront origin to the bucket’s REST API endpoint (mlem-website.s3.us-east-1.amazonaws.com) instead of the website endpoint. —Taz

answered 10 months ago

  • That's interesting, all of the guides and the AWS UI seem to push developers in the direction of creating a public static website first, and linking to that via CloudFront. I'll make the change, thanks!

0

The 503 LimitExceeded errors you're experiencing are likely related to Amazon S3 request rate limits. When using S3 as an origin for CloudFront, S3 has specific request rate limits per prefix. For a single prefix, S3 can handle 3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second.

Even though you're the only user testing the site, if your static website has many resources (images, CSS, JavaScript files, etc.) that are all stored under the same prefix in your S3 bucket, CloudFront might be sending too many requests to that prefix simultaneously when loading the page.

Here are some solutions to try:

  1. Distribute your objects across multiple prefixes in your S3 bucket. For example, instead of storing all files at the root level, organize them into folders like /images/, /css/, /js/, etc. This allows S3 to scale up to handle requests for each prefix separately.

  2. Ensure your CloudFront distribution is properly caching content. Since you mentioned you've set the Cache Policy to "CachingDisabled," CloudFront is forwarding every request to your origin. Change this back to "CachingOptimized" to reduce the number of requests hitting your S3 bucket.

  3. If you're using the S3 website endpoint as your origin, consider switching to the S3 REST API endpoint with Origin Access Control (OAC) instead. This is the recommended approach for serving S3 content through CloudFront and may handle the request patterns differently.

  4. Implement a gradual loading strategy for your website resources to avoid sending too many simultaneous requests to the same S3 prefix.

The fact that the site works when accessing it directly through S3 but fails through CloudFront suggests that CloudFront might be sending requests to S3 in a more concentrated burst than when you access the site directly, potentially hitting the S3 rate limits.
Sources
HTTP 503 status code (Service Unavailable) - Amazon CloudFront
Access Denied for CloudFront to S3 static site | AWS re:Post

answered 10 months ago

EXPERT

reviewed 10 months ago

0

Original Poster here! I went through a lot of testing, but I diagnosed that the CloudFront free-tier has burst limit to the number of simultaneous HTTP requests you can make before you start getting 503 errors.

There's no perfect solution to this, my best advice is to change to another plan entirely, I had success eliminating this issue when testing a pay-as-you go distribution.

However I did try to make the free-tier distribution work, I figured I could put in a queue system to my fetch() commands and limit their speed to avoid the limitations, and then add a retry system if I do catch a 503 error, so here's what I tried.

  • Created a request-manager.js utility script to queue my fetch() requests on my website
  • Exposed two variables that are accessible via URL parameters
  • 'request-limit' sets the number of simultaneous request. Defaults to '999'
  • 'request-delay' sets a time delay between the batches of requests in milliseconds (1000 == 1 second). Defaults to '0' for no delay

In testing, if I set my 'request-limit' to '10' and my 'request-delay' to '100', that seems to be good enough to not trigger the burst limit.

https://d3n5jstxb8npc3.cloudfront.net/?request-limit=10&request-delay=100

In addition I implemented a retry system into my queue system, but even though 503 errors are logged in the console, I can't catch them in my fetch() responses, because they appear as 200 'ok' status by the time my Javascript reads the response.

I also have another distribution for testing, using the pay-as-you-go plan. It works 100% correct without setting any arbitrary limits to my fetch() commands.

https://d2054d2g70vrs.cloudfront.net/

If anyone knows of a way to lift this limitation in the free-tier, please let me know! Also if this isn't going to change, I heavily recommend AWS acknowledge this limitation and add it to their documentation so future engineers can avoid this bug-hunt in the future.

answered 10 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.