Find out who generated the error
Response headers tell you:
x-cache: Error from cloudfront→ CloudFront returned an error. It may be passing on an origin error.server: AmazonS3→ S3 sent the 403 or 404.- A 403 with an HTML page mentioning "Request blocked" → AWS WAF.
Turn on standard logs or real-time logs and look at x-edge-result-type, x-edge-detailed-result-type and the status code.
403 with an S3 origin
- Using Origin Access Control (OAC), and the bucket policy allows the CloudFront service principal for this distribution:
{ "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::web-assets/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1ABCDEF" } } } - Objects encrypted with SSE-KMS: the key policy must allow the CloudFront service principal
kms:Decryptwith the same SourceArn condition. - The object exists. Without
s3:ListBucket, a missing key returns 403, not 404. - The default root object (
index.html) is set. For single-page apps, sub-paths need a custom error response or a CloudFront Function rewrite. - The origin is the S3 REST endpoint (
bucket.s3.region.amazonaws.com), not the website endpoint, when you use OAC.
502 with a custom origin (ALB, EC2, on-premises)
| Cause | Fix |
|---|---|
| Origin certificate doesn't match the origin domain name | The certificate must cover the origin domain CloudFront connects to (or the forwarded Host header) |
| Certificate expired or chain incomplete | Install the full chain. Self-signed certificates aren't accepted. |
| TLS protocols or ciphers mismatch | Allow TLS 1.2 on the origin, and match the Origin SSL protocols setting |
| Origin unreachable on the configured port | Security group / WAF on the ALB must allow CloudFront (use the com.amazonaws.global.cloudfront.origin-facing managed prefix list) |
openssl s_client -connect origin.contoso.com:443 -servername origin.contoso.com </dev/null 2>/dev/null | openssl x509 -noout -subject -enddate -ext subjectAltName
504
The origin didn't respond within the origin response timeout (30 s by default). Raise it in the origin settings (the maximum may need a quota increase), or speed up or make the slow endpoint asynchronous.
Errors keep showing after the fix
CloudFront caches error responses (by default for 10 seconds; check your custom error response settings). Invalidate the paths:
aws cloudfront create-invalidation --distribution-id E1ABCDEF --paths "/index.html" "/assets/*"
Tip
Use versioned file names (
app.3f9a2c.js) for static assets, so deployments never need wide invalidations.