CloudFront 502 and 504 Errors: Origin Problems Explained and Fixed
A CloudFront 502 means CloudFront never managed to connect to your origin at all — a TCP or SSL/TLS problem. A CloudFront 504 means it did connect, but the origin either took too long to answer or handed back an error of its own. They point you toward completely different fixes, so the first thing to do is figure out which one you actually have, not start clicking around the console.
Here's the part that trips almost everyone up first: invalidating your cache fixes nothing here. An invalidation tells CloudFront to stop serving a stale cached copy of an object — it has nothing to do with whether CloudFront can reach your origin server. If your origin is unreachable, CloudFront will just try to reach it again after the invalidation, fail again, and hand you the same 502 or 504. People burn a Saturday running invalidation after invalidation on a connectivity problem that an invalidation was never built to touch.
Wait, if you are a new reader here and don't know about AWS because you didn't had money to learn or from Non Tech background, don't feel bad! I had create one hub, start from here: Learn AWS its free, and all in plain english so it will be easier for u to understand.. once its done come back here, it will be more easier..! Now, let's go back to topic first question as usual, let's question the assumptuons
The one-question diagnostic: 502 or 504?
Look at the exact wording of the error page CloudFront showed you. It tells you almost everything before you open the console.
♂️ Jake's Reality Check
Jake: "I ran three invalidations on the whole distribution and nothing changed. Am I doing it wrong?"
Ethan didn't even open the console. "Invalidation clears cache, Jake. That's the entire job it does. You could invalidate that distribution a thousand times and it wouldn't touch whatever's actually stopping CloudFront from reaching your server. Different problem, different tool."
If the page reads "502 ERROR — CloudFront wasn't able to connect to the origin," you have a connection-establishment failure: DNS, TCP, or the SSL/TLS handshake never completed. If it reads "504 ERROR — CloudFront attempted to establish a connection with the origin, but either the attempt failed or the origin closed the connection," CloudFront got further — it connected, sent the request, and then either the origin took longer than CloudFront's timeout to answer, or the origin itself returned a 504. Sometimes you'll also see an error code like NonS3OriginDnsError printed on the page or in your logs, which is CloudFront being explicit that it's a DNS resolution failure, not a slow server.
One more clue worth checking before you touch any settings: open your CloudFront distribution in the console, click the Origins tab, and confirm exactly which origin the request is actually hitting. On distributions with multiple origins or an origin group, it's common to spend twenty minutes debugging the wrong backend.
What "CloudFront wasn't able to connect to the origin" (502) actually means
CloudFront returns an HTTP 502 status code when it wasn't able to serve the requested object because it couldn't connect to the origin server. That's a narrower statement than it sounds — it doesn't mean the origin is down in every case. It means the specific connection attempt CloudFront made didn't succeed, and AWS's documentation narrows that down to a short, specific list of causes:
- An SSL/TLS negotiation failure because your origin is offering protocols or ciphers CloudFront doesn't support.
- An SSL/TLS negotiation failure because the origin's certificate is expired, invalid, self-signed, or the certificate chain is in the wrong order.
- A host header mismatch during the SSL/TLS negotiation between CloudFront and a custom origin.
- The custom origin isn't responding on the ports specified in the origin settings.
- The custom origin ends the connection too quickly.
- A DNS configuration problem — CloudFront can't resolve the origin's domain name at all (this shows up as
NonS3OriginDnsError). - If you're running Lambda@Edge, a malformed function response.
- If you're running a CloudFront function, an attempt to add, delete, or change a read-only header.
♂️ Jake's Reality Check
Jake: "So it's not about how much traffic we're getting? I figured we finally got popular enough to break something."
Ethan laughed. "I wish. No — a 502 has nothing to do with load. It's plumbing between CloudFront and your server, not a crowd problem. Nobody breaks a website by liking it too much."
✅ Why check this first
Certificate and cipher problems cause the large majority of custom-origin 502s people report. Start there before chasing anything more exotic — it's the fastest path to a fix for most readers.
Fixing 502 errors, cheapest fix first
Work down this list in order. Most people find their cause in the first three steps.
- Confirm the origin is up on its own. Hit the origin's DNS name directly in a browser or with
curl, bypassing CloudFront entirely. If that fails too, this was never a CloudFront problem — fix the origin first. - Check DNS resolution from a public network. Run
dig OriginDomainNameornslookup OriginDomainNamefrom a machine on the open internet (not your office VPN, not a private subnet). CloudFront resolves your origin using public DNS, so you need to test in the same context it does. If this comes back empty or wrong, the problem is with your DNS provider or Route 53 hosted zone, not CloudFront. - Check the origin's SSL/TLS certificate. Run an online SSL checker or
openssl s_client -connect origindomain:443against your origin. Confirm the certificate isn't expired, isn't self-signed, and that the full chain — including the intermediate certificate — is present and in the correct order. If any of those is wrong, CloudFront drops the TCP connection outright and returns a 502. - Confirm the certificate's domain name matches. The name on the origin's certificate has to match either the Origin Domain you set in the distribution, or the Host header CloudFront forwards — whichever your origin is checking against. A mismatch fails the handshake even if the certificate itself is perfectly valid.
- Check which ports and protocol CloudFront is actually using. In the Origins tab, open your origin and confirm the HTTP port, HTTPS port, and Origin Protocol Policy match what your server is actually listening on. By default CloudFront uses 80/443, but if your app runs on a custom port and the origin setting still says 443, every request fails before it starts.
- Check firewalls and security groups for CloudFront's IP ranges, not just "is the server up." A server can be fully healthy and still refuse every CloudFront connection if a security group only allows your office IP.
⚠️ What self-signed certificates actually break
CloudFront documentation is explicit that a self-signed certificate on your origin will not work for HTTPS communication with a custom origin — not "works with a warning," not "works if you accept it once." CloudFront drops the connection and returns a 502 every single time. If you're testing with a self-signed cert because a real one felt like overkill for an EC2-only origin, this is the wall you're hitting.
SSL/TLS causes of 502, in more depth
Since this is where most 502s live, it's worth slowing down. CloudFront connects to origins using a specific set of supported ciphers and protocols — if your origin's web server (Apache, nginx, IIS, whatever's terminating TLS) only offers a set that doesn't overlap with CloudFront's supported list, the handshake fails before either side sends any real data. You can check this with SSL Labs' test tool: put in your origin's domain, run the test, and compare the Protocols and Cipher Suites sections against what CloudFront documents as supported. This is a common trap right after a server OS upgrade quietly disables an older TLS version your load balancer or app server was still configured to prefer.
The host header mismatch case is subtler and catches people who recently moved a site behind a custom domain. If you just finished setting up HTTPS with a custom domain and Route 53 — the kind of setup covered in our walkthrough of custom domains with CloudFront and Route 53 — double check that the certificate on the origin side (not the ACM certificate on the CloudFront side, the one on the actual origin server) covers whichever hostname CloudFront is forwarding as the Host header. Those are two separate certificates serving two separate purposes, and it's easy to get the ACM one right and forget the origin-side one entirely.
| Symptom | Likely cause | Check first |
|---|---|---|
502 with error code NonS3OriginDnsError |
DNS can't resolve the origin domain | dig/nslookup against public DNS |
| 502, X-Cache header shows "Error from cloudfront" | SSL/TLS handshake failure of some kind | openssl s_client against the origin |
| 502 only after deploying a Lambda@Edge function | Malformed function response | CloudWatch logs for the function region |
| 502 only after deploying a CloudFront function | Function tries to modify a read-only header | Function code, not the origin |
What "Gateway Timeout" (504) actually means
A 504 means CloudFront successfully forwarded your request to the origin — the connection worked, unlike a 502 — and then one of two things happened: the origin itself returned an HTTP 504, or the origin simply didn't respond before CloudFront's own timeout expired. AWS's documentation is direct about where to look first: check whether traffic to the origin is blocked by a firewall or security group, or whether the origin is even reachable on the public internet, before you go anywhere near timeout values.
♂️ Jake's Reality Check
Jake: "Could I just point CloudFront at our internal load balancer instead of the public one? Our security guy says internal is safer."
"He's right that internal is safer — and wrong that it works here," Ethan said. "CloudFront's edge locations only reach the public internet. Point it at something internal and you don't get an occasional error, you get a 504 on every single request, forever."
Jake pushed back: "So we just... expose it? That feels backwards." — "No," Ethan said. "You use a VPC origin. That's the setting built for exactly this: CloudFront reaches in without you opening the thing up."
That last point trips up people migrating an app into a VPC for the first time. It's tempting to assume "internal" is more secure and CloudFront will just reach in — it won't. If you genuinely need the origin to stay private, the supported path is a VPC origin, not an internal load balancer CloudFront was never able to reach in the first place.
Fixing 504 errors, in order
- Confirm the origin is reachable from the public internet at all. Not from your laptop on the office network — from outside it. If you get EC2 status check failures alongside the 504, the instance itself may be the problem before CloudFront enters the picture; our EC2 status check failed guide walks through diagnosing that.
- Check your origin's firewall and security groups for CloudFront's IP ranges. If you're on an Application Load Balancer or EC2 origin, use the CloudFront managed prefix list in your security group rules rather than a hand-maintained IP list, since CloudFront's published ranges change over time.
- Look at how long the application actually takes to respond, independent of CloudFront. A slow database query, a cold-starting container, or a synchronous call to a third-party API can all push response time past CloudFront's timeout even though nothing is "broken."
- Only then, raise the origin's response timeout, if the application genuinely needs longer than 30 seconds and you've confirmed that's the actual bottleneck, not a symptom of something slower that should be fixed instead.
Ethan is blunt about that order: "Raising the timeout before you've confirmed reachability just means you wait longer to get the same 504. And if you raise it before fixing a genuinely slow backend, you've turned a fast failure into a slow one for every visitor. That's not a fix, that's a worse version of the problem."
Origin timeout settings, explained
These settings only apply to custom origins and VPC origins, not to S3 bucket origins accessed through the REST API endpoint (more on that distinction in the next section). There are three separate values, and confusing them wastes time:
| Setting | Default | What it governs |
|---|---|---|
| Origin connection timeout / attempts | 10 seconds × 3 attempts | How long CloudFront tries to establish the connection before giving up or failing over to a secondary origin (up to 30 seconds total by default) |
| Origin response timeout (read timeout) | 30 seconds | How long CloudFront waits for the origin's response once connected, before returning a 504 |
| Keep-alive timeout | 5 seconds | How long CloudFront holds the connection open after a response, hoping to reuse it for the next request |
To change response or keep-alive timeout, go to the CloudFront console, open your distribution, select the Origins tab, choose your origin, click Edit, and expand Additional settings. Both values can be raised up to 60 seconds directly; going beyond that, up to a documented maximum of 180 seconds, requires filing a service quota increase request first, and then updating the origin settings to match — a quota increase alone doesn't change anything on an existing distribution until you go back and raise the value yourself.
✅ Ethan's rule of thumb
"A slow origin under load stays slow whether CloudFront waits 30 seconds or 180," Ethan says. "Raising the timeout mostly changes how long your visitor stares at a spinner before eventually getting an error anyway. I treat the timeout as a safety margin, never a solution."
S3 origin vs. custom origin: different failure modes
This distinction matters more than most guides admit. An S3 bucket accessed through S3's REST API endpoint is treated by CloudFront as an S3 origin, with its own connection handling — the SSL/TLS negotiation and timeout settings above don't apply to it the same way, so certificate and cipher troubleshooting is largely irrelevant there. But an S3 bucket configured for static website hosting, and accessed through its website endpoint, is treated as a custom origin. Everything in this post about ports, protocols, and timeouts applies to that setup, even though it's "just S3."
| Origin type | Treated as | 502/504 causes to check |
|---|---|---|
| S3 bucket, REST endpoint (typical, with OAC) | S3 origin | Bucket policy, Origin Access Control, region mismatch |
| S3 bucket, static website hosting endpoint | Custom origin | Port/protocol settings, response timeout |
| EC2, ALB, on-prem server | Custom origin | Everything covered in this post |
Application Load Balancer origins: the keep-alive trap
If your origin is an ALB in front of EC2 instances, there's a specific failure worth knowing by name: a mismatch between the keep-alive timeout on your actual application server (Apache, nginx, your app framework) and the idle timeout configured on the load balancer. If the application's keep-alive is shorter than the load balancer's idle timeout, the application can close the connection while the load balancer still believes it's open and has an outstanding request on it — the load balancer then returns its own 502 to whoever's in front of it, in this case CloudFront. AWS's troubleshooting guidance for this exact case is to make sure the application's keep-alive timeout is set longer than the load balancer's idle timeout, not the other way around.
♂️ Jake's Reality Check
Jake: "An ALB feels like overkill for a phone shop site. Do we even need one?"
"For a low-traffic site, maybe not," Ethan admitted. "But if you ever do add one, this timeout mismatch is the thing that bites people under load, not under quiet Tuesday-afternoon traffic. It's worth knowing before you need it, not after."
To separate whether the load balancer or the target (your EC2 instance) is the actual source, check CloudWatch: a data point on HTTPCode_ELB_502_Count points at the load balancer itself, while HTTPCode_Target_5XX_Count points at your instances. Access logs give the same answer — an elb_status_code of 502 with a target_status_code of "-" means the load balancer never even reached the target.
Lambda@Edge and CloudFront Functions: the case people forget to check
If a 502 started right after you deployed or updated an edge function, stop checking the origin and check the function. With Lambda@Edge, a 502 can mean the function's response was malformed or contained invalid content — check the function's CloudWatch logs, which for Lambda@Edge live in the region closest to where the request was served, not necessarily your function's home region.
With CloudFront Functions, a 502 specifically means the function is trying to add, delete, or change a header that's marked read-only. The unhelpful part: this error doesn't show up while you're testing the function in the console — it only appears once the function is deployed and a real request runs through it. If your 502 started right after a function deployment, check the function code for header modifications before you look anywhere near the origin.
♂️ Jake's Reality Check
Jake: "I don't even know if we have a Lambda@Edge function running. How would I check?"
"Open your distribution's behaviors tab," Ethan said. "Each cache behavior lists any function associations under it, Lambda@Edge or CloudFront Functions, and which event type they run on. Empty section, this cause doesn't apply to you, skip it and move on."
When you've checked everything and it's still broken
A few genuinely stubborn cases, in the order worth trying:
- Intermittent, not constant. If the error comes and goes across different requests, suspect an origin group with a secondary origin that's itself unhealthy, or capacity that's marginal under load rather than fully down. Check CloudWatch's origin latency and error rate metrics for patterns tied to traffic spikes.
- Someone else owns the account or the origin, and you can't reach them. Confirm you can see the actual origin the distribution points to (Origins tab, as covered above) and work from there — you can diagnose most of this without needing the original builder's cooperation, but you can't fix a certificate or firewall rule you don't have access to change.
- Everything above checks out and it's still failing. At that point, open a support case with AWS and include the exact request ID from the error page — it's printed at the bottom of both the 502 and 504 error pages and lets AWS support trace the specific failed request server-side, which is far faster than describing the symptom in words.
⚠️ What we can't tell you from here
If your origin genuinely isn't reachable from the public internet — a private subnet with no route out, a security group locked to a single office IP, a load balancer marked internal — there is no CloudFront setting, cache behavior, or function that gets around that. The fix has to happen on the origin side of the line, not in the distribution config.
Frequently asked questions
Does invalidating my CloudFront cache fix a 502 or 504?
No. Invalidation removes cached objects so CloudFront re-fetches them from the origin on the next request. It has no effect on whether CloudFront can connect to that origin in the first place.
Is a 502 CloudFront's fault or my origin's fault?
Almost always the origin's, or the network path to it. CloudFront returns a 502 specifically because it couldn't establish or complete a connection to your origin — a certificate, port, DNS, or firewall problem on that side.
Can I use a self-signed certificate on my origin?
No, not for HTTPS communication between CloudFront and a custom origin. CloudFront drops the connection and returns a 502 every time it encounters one.
Why does the error mention NonS3OriginDnsError specifically?
That code means CloudFront tried to resolve your origin's domain name using public DNS and couldn't. It's a narrower, more specific case of a 502 — check your DNS provider or Route 53 hosted zone rather than the origin server itself.
What's the actual difference between a 502 and a 504 in plain terms?
A 502 means CloudFront never got a connection open with the origin. A 504 means the connection opened fine, but the origin was too slow to answer or returned an error of its own once it did.
Can CloudFront reach an origin on a private subnet or internal load balancer?
No. CloudFront edge locations connect over the public internet. Anything not publicly reachable will return a 504 every time, not intermittently. Use a VPC origin if the origin needs to stay off the public internet.
What's the default origin response timeout, and can I raise it?
30 seconds by default. You can raise it up to 60 seconds directly in the console; beyond that, up to a maximum of 180 seconds, you need a service quota increase first, then you still have to update the origin settings yourself to use the new value.
Should I just raise the timeout until the errors stop?
Only after confirming the origin is reachable and that slowness, not unreachability, is the actual problem. Raising the timeout on an unreachable or genuinely broken origin just makes visitors wait longer for the same failure.
My origin is an S3 bucket — do timeout settings apply to me?
Depends how it's connected. Through the S3 REST API endpoint (the common setup with Origin Access Control), no — it's treated as an S3 origin. Through the static website hosting endpoint, yes — that's treated as a custom origin and everything about ports, protocols, and timeouts applies.
I have an Application Load Balancer origin and get 502s under load. What's specific to ALB?
Check for a keep-alive mismatch: if your application server's keep-alive timeout is shorter than the load balancer's idle timeout, the app can close a connection the load balancer still thinks is active, producing a 502. Set the application's keep-alive longer than the load balancer's idle timeout.
How do I tell if the 502 is coming from my load balancer or my EC2 target?
Check CloudWatch: a data point on HTTPCode_ELB_502_Count means the load balancer; HTTPCode_Target_5XX_Count means the target instance. Access logs work too — a target_status_code of "-" means the load balancer never reached the target at all.
I just deployed a Lambda@Edge or CloudFront function and started seeing 502s. Is that related?
Very likely, yes. For Lambda@Edge, check the function's CloudWatch logs for a malformed response. For CloudFront Functions, check whether the function tries to modify a read-only header — this error only appears after deployment, never during console testing.
What are the CloudFront connection timeout and connection attempts settings?
They control how long CloudFront tries to establish a connection before giving up: 10 seconds per attempt, 3 attempts by default, so up to 30 seconds total before CloudFront fails over to a secondary origin (if one's configured) or returns an error to the visitor.
Does a 502 or 504 affect my whole site or just some pages?
Depends on the cause. A DNS or certificate problem on the origin typically breaks every request that isn't already cached. A single slow endpoint or a specific edge function tied to one cache behavior can affect only the pages that route through it.
What information should I have ready before contacting AWS support?
The exact request ID printed at the bottom of the error page, the approximate time the error occurred, and whether it's constant or intermittent. That request ID lets AWS trace the specific failed request server-side rather than working from a description.
Can a firewall or security group cause a 504 even if the server itself is healthy?
Yes, and it's one of the two things AWS's own documentation says to check before anything else. A perfectly healthy server behind a security group that blocks CloudFront's IP ranges will return a 504 on every request.
- Setting up a custom domain with HTTPS on CloudFront and Route 53
Useful if your 502 traces back to a certificate mismatch right after this kind of setup. - Fixing an EC2 status check failure
Start here if your origin is EC2 and the 504 comes with instance health warnings too.
Revision note. Written August 2026, covering current CloudFront origin behavior for S3, custom, ALB, and Lambda@Edge/CloudFront Functions origins. This will need a look whenever AWS changes the standard timeout ceiling or adds new managed origin types like VPC origins to the mix. If you've been staring at this error page for a while now, take a breath — it's almost always one specific, findable thing, not something wrong with you.Happu learning