S3静态网站HTTPS访问时路由重定向失效问题排查
Hey there, let's figure out why your S3 routing rule fails over HTTPS (via CloudFront) but works when hitting the S3 HTTP endpoint directly, plus how to fix it.
The core issue here is almost certainly your CloudFront distribution pointing to S3's REST API endpoint instead of the dedicated S3 Static Website Hosting endpoint.
Here's the breakdown:
- When you hit
http://example.com.s3-website.ca-central-1.amazonaws.com/login, you're sending requests directly to S3's static website endpoint. This endpoint is designed to process your<RoutingRules>configurations, so the redirect fires as expected. - But when you access
https://(www.)example.com/loginvia CloudFront, if your CloudFront origin is set to the standard S3 REST endpoint (e.g.,example.com.s3.amazonaws.com), S3 won't execute your static website routing rules. The REST endpoint doesn't support static website features like routing rules, index documents, or custom error pages—it's meant for programmatic object access, not serving websites.
A secondary possible issue could be CloudFront caching stale responses, but the origin endpoint mismatch is the most common culprit here.
You've got two solid options to fix this:
方案1:调整CloudFront指向S3静态网站端点
This keeps using your existing S3 routing rules. Follow these steps:
- Open the AWS Console, navigate to CloudFront, and select your distribution.
- Go to the Origins tab, then edit your S3 origin.
- For the
Origin domainfield, don't pick the auto-populated S3 bucket option. Instead, manually paste your S3 static website endpoint (e.g.,example.com.s3-website.ca-central-1.amazonaws.com). - Set
Origin protocol policyto HTTP only—S3 static website endpoints don't support HTTPS, but CloudFront will handle the HTTPS-to-HTTP conversion and return HTTPS redirects to users (per your routing rule's<Protocol>https</Protocol>setting). - Head to the Behaviors tab, edit your default behavior:
- Under
Cache key and origin requests, make sure you're passing necessary headers (adding theHostheader can help ensure S3 processes the request correctly). - Temporarily set
Default TTLto 0 to avoid caching stale redirects while testing (you can adjust this later once everything works).
- Under
- Wait for CloudFront to deploy the changes (usually 5-15 minutes), then test your HTTPS login paths.
If you want the redirect to support both www.example.com/login and example.com/login pointing to their respective app subdomains, you can set up a Route53 alias record for www.app.example.com pointing to app.example.com—that way, your single existing routing rule will work for both source domains, since the redirect target will resolve correctly regardless of the www prefix.
方案2:Use Lambda@Edge for more flexible redirects
If you want greater control (or don't want to rely on S3's limited routing rules), you can add a Lambda@Edge function to CloudFront that handles the redirect logic directly. This is especially useful if you have more complex routing needs down the line.
Here's a sample function that triggers on viewer requests and redirects based on the original request's host:
exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const uri = request.uri; const host = request.headers.host[0].value; // Match any path starting with /login if (uri.startsWith('/login')) { // Preserve the www prefix from the original request const appHost = host.startsWith('www.') ? 'www.app.example.com' : 'app.example.com'; const redirectUrl = `https://${appHost}${uri}`; const response = { status: '302', statusDescription: 'Found', headers: { location: [{ key: 'Location', value: redirectUrl }] } }; callback(null, response); } // Pass through all other requests normally callback(null, request); };
To set this up:
- Create this Lambda function in the
us-east-1region (required for Lambda@Edge). - Publish a version of the function.
- Go back to your CloudFront distribution's Behaviors tab, edit your default behavior.
- Under Lambda function associations, add a trigger for
Viewer Requestand select your published Lambda function version. - Deploy the CloudFront changes and test.
This approach automatically handles both www and non-www source domains, no extra S3 routing rules needed.
内容的提问来源于stack exchange,提问作者Jay Bell

