Introduction to CloudFront Troubleshooting
Amazon CloudFront is a fast content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally with low latency and high transfer speeds. While CloudFront is generally reliable, developers often encounter configuration issues, caching problems, and access control errors that can disrupt content delivery.
This tutorial covers the most common CloudFront issues developers face and provides practical solutions with code examples to help you diagnose and fix problems quickly.
>>> NEW: The Self-Hosted Agent Factory — Production Kit
Run a 3-agent production line (orchestrator + workers + adversarial QC) on a $6/mo VPS. 120-page book + the complete working Docker stack: task ledger, model router, 15-min watchdog, QC rubric.
Why CloudFront Troubleshooting Matters
Effective troubleshooting is critical because CloudFront sits between your users and your origin servers. When issues occur, they can affect:
- User experience — Slow load times or errors directly impact customer satisfaction
- SEO rankings — Search engines penalize sites with poor performance or availability
- Cost efficiency — Misconfigured caching leads to unnecessary origin requests and higher costs
- Security posture — Incorrect access controls can expose sensitive content
- Application functionality — Broken paths or headers can break dynamic applications
Common CloudFront Issues and Solutions
1. Access Denied (403) Errors
One of the most frequent CloudFront errors is the 403 Forbidden response. This typically occurs due to misconfigured origin access, missing S3 bucket policies, or incorrect IAM permissions.
Common causes:
- S3 bucket not allowing CloudFront access via Origin Access Identity (OAI)
- Bucket set to private without proper policy
- WAF rules blocking legitimate traffic
- Lambda@Edge function returning 403
Solution: Configure the S3 bucket policy to allow CloudFront OAI access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontOAI",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXX1234"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
You can also verify the OAI configuration using the AWS CLI:
aws cloudfront get-distribution-config \
--id E1234567890ABC \
--query 'DistributionConfig.Origins.Items[0].S3OriginConfig.OriginAccessIdentity'
2. Caching Issues and Stale Content
CloudFront may serve stale content when cache behaviors are misconfigured or when origin headers prevent caching. This is particularly problematic for dynamic applications where content updates frequently.
Symptoms:
- Updated content not appearing for users
- Inconsistent content across edge locations
- Cache hit ratio lower than expected
Solution: Create an invalidation to clear cached content:
aws cloudfront create-invalidation \
--distribution-id E1234567890ABC \
--paths "/*" \
--query 'Invalidation.Id'
For targeted invalidations, specify individual paths:
aws cloudfront create-invalidation \
--distribution-id E1234567890ABC \
--paths "/images/*" "/css/styles.css" "/api/data.json"
To prevent future caching issues, configure proper cache behaviors with appropriate TTLs:
{
"PathPattern": "/api/*",
"TargetOriginId": "my-origin",
"ViewerProtocolPolicy": "redirect-to-https",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ForwardedValues": {
"QueryString": true,
"Cookies": {
"Forward": "all"
},
"Headers": {
"Quantity": 2,
"Items": ["Authorization", "Origin"]
}
},
"MinTTL": 0,
"DefaultTTL": 0,
"MaxTTL": 0
}
3. SSL/TLS Certificate Problems
SSL certificate issues can cause browsers to display security warnings or refuse to connect entirely. These problems often arise during certificate renewal or when configuring custom domains.
Common causes:
- Certificate not deployed in us-east-1 region
- Domain validation incomplete
- Mismatch between alternate domain names and certificate
- Intermediate certificate chain missing at origin
Solution: Verify certificate status and ensure it is in us-east-1:
aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/abc123 \
--region us-east-1 \
--query 'Certificate.{Status:Status,DomainNames:DomainValidationOptions}'
Test the SSL configuration using openssl:
openssl s_client -connect example.com:443 \
-servername example.com \
< /dev/null 2>/dev/null | openssl x509 -noout -subject -dates
4. Origin Timeout and 502/504 Errors
When CloudFront cannot reach your origin or the origin takes too long to respond, users see 502 Bad Gateway or 504 Gateway Timeout errors. These are critical issues that require immediate attention.
Troubleshooting steps:
First, check if the origin is reachable directly:
curl -I -v --resolve example.com:443:ORIGIN_IP https://example.com/path
Review CloudFront distribution settings for timeout configuration:
aws cloudfront get-distribution-config \
--id E1234567890ABC \
--query 'DistributionConfig.Origins.Items[0].CustomOriginConfig.{Timeout:OriginReadTimeout,KeepAlive:OriginKeepaliveTimeout}'
Update timeout values if your origin requires more processing time:
aws cloudfront update-distribution \
--id E1234567890ABC \
--if-match ETAG_VALUE \
--distribution-config file://updated-config.json
In the updated config JSON, adjust the origin settings:
{
"Origins": {
"Items": [
{
"Id": "my-origin",
"DomainName": "origin.example.com",
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginReadTimeout": 60,
"OriginKeepaliveTimeout": 5,
"OriginSslProtocols": {
"Quantity": 2,
"Items": ["TLSv1.2", "TLSv1.1"]
}
}
}
]
}
}
5. CORS Errors with API Responses
When serving APIs through CloudFront, CORS (Cross-Origin Resource Sharing) errors frequently occur because CloudFront caches responses without the necessary CORS headers.
Solution: Configure CloudFront to forward the Origin header and use a Lambda@Edge function to add CORS headers:
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
headers['access-control-allow-origin'] = [{
key: 'Access-Control-Allow-Origin',
value: '*'
}];
headers['access-control-allow-methods'] = [{
key: 'Access-Control-Allow-Methods',
value: 'GET, POST, PUT, DELETE, OPTIONS'
}];
headers['access-control-allow-headers'] = [{
key: 'Access-Control-Allow-Headers',
value: 'Content-Type, Authorization, X-Requested-With'
}];
callback(null, response);
};
For the cache behavior, ensure the Origin header is forwarded:
{
"PathPattern": "/api/*",
"ForwardedValues": {
"QueryString": true,
"Headers": {
"Quantity": 1,
"Items": ["Origin"]
}
}
}
6. Redirect Loops (HTTP to HTTPS)
Redirect loops occur when both CloudFront and the origin attempt to enforce HTTPS, creating an infinite redirect cycle that prevents the page from loading.
Solution: Set the origin protocol policy to "HTTPS only" and let CloudFront handle the viewer-to-edge redirect:
aws cloudfront get-distribution-config \
--id E1234567890ABC \
--query 'DistributionConfig.Origins.Items[0].CustomOriginConfig.OriginProtocolPolicy'
Ensure the ViewerProtocolPolicy is set correctly:
{
"ViewerProtocolPolicy": "redirect-to-https",
"Origins": {
"Items": [
{
"CustomOriginConfig": {
"OriginProtocolPolicy": "https-only"
}
}
]
}
}
At the origin level (e.g., nginx), disable HTTP-to-HTTPS redirects since CloudFront already handles this:
server {
listen 80;
server_name example.com;
# Do NOT redirect here - CloudFront handles HTTPS
# Just return 404 for direct origin access
return 404;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
7. Lambda@Edge Function Errors
Lambda@Edge functions can fail silently, causing unexpected behavior. Debugging is challenging because functions run across multiple edge locations.
Solution: Enable CloudWatch Logs and check logs in the us-east-1 region:
aws logs describe-log-groups \
--region us-east-1 \
--log-group-name-prefix "/aws/cloudfront" \
--query 'logGroups[].logGroupName'
Implement proper error handling in your Lambda@Edge function:
exports.handler = async (event) => {
try {
const request = event.Records[0].cf.request;
// Modify request headers
request.headers['x-custom-header'] = [{
key: 'X-Custom-Header',
value: 'custom-value'
}];
return request;
} catch (error) {
console.error('Lambda@Edge error:', error);
// Return the original request on error
return event.Records[0].cf.request;
}
};
Best Practices for CloudFront Troubleshooting
Use CloudFront Response Headers for Debugging
Enable response header logging to trace requests through the CloudFront pipeline:
aws cloudfront update-distribution \
--id E1234567890ABC \
--if-match ETAG_VALUE \
--distribution-config file://config-with-headers.json
In the config, enable the response headers policy:
{
"ResponseHeadersPolicyId": "60669652-45bed-415d-885d-22c33cc0b93b"
}
Implement Comprehensive Monitoring
Set up CloudWatch alarms for key metrics:
aws cloudwatch put-metric-alarm \
--alarm-name "CloudFront-HighErrorRate" \
--alarm-description "Alert when 4xx/5xx error rate exceeds threshold" \
--namespace AWS/CloudFront \
--metric-name 5xxErrorRate \
--dimensions Name=DistributionId,Value=E1234567890ABC Name=Region,Value=Global \
--statistic Average \
--period 300 \
--threshold 1.0 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts
Maintain a Troubleshooting Checklist
- Verify distribution status is "Deployed" before testing changes
- Check both viewer and origin access logs for discrepancies
- Test from multiple geographic locations to identify edge-specific issues
- Use
curl -vwith appropriate headers to debug request/response cycles - Validate cache key settings to ensure proper cache behavior
- Review WAF rules that might be blocking legitimate traffic
- Confirm Route 53 DNS records point to the correct CloudFront distribution
- Monitor origin health checks and configure failover origins when needed
Leverage CloudFront Logs for Analysis
Enable standard logging and analyze with Athena:
CREATE EXTERNAL TABLE cloudfront_logs (
date DATE,
time STRING,
location STRING,
bytes BIGINT,
request_ip STRING,
method STRING,
host STRING,
uri STRING,
status INT,
referrer STRING,
user_agent STRING,
query_string STRING,
cookie STRING,
result_type STRING,
request_id STRING,
host_header STRING,
protocol STRING,
edge_location STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LOCATION 's3://my-logs-bucket/cloudfront/'
TBLPROPERTIES ('skip.header.line.count'='2');
Query for error patterns:
SELECT
uri,
status,
COUNT(*) as request_count,
COUNT(DISTINCT request_ip) as unique_ips
FROM cloudfront_logs
WHERE status >= 400
AND date >= DATE '2024-01-01'
GROUP BY uri, status
ORDER BY request_count DESC
LIMIT 20;
Conclusion
Troubleshooting CloudFront requires a systematic approach that considers the entire request lifecycle from the viewer through the edge location to the origin. By understanding common issues like access denied errors, caching problems, SSL misconfigurations, origin timeouts, CORS errors, redirect loops, and Lambda@Edge failures, you can quickly identify and resolve problems before they impact your users. Implementing robust monitoring, maintaining proper logging, and following best practices for configuration management will help you maintain a reliable and performant CDN setup. Remember that CloudFront changes take time to propagate globally, so always verify deployment status and test thoroughly after making configuration changes. With these tools and techniques at your disposal, you can confidently manage and troubleshoot your CloudFront distributions in production environments.