πŸš€ Fixing CloudFront "Forbidden" Errors with CloudFront Functions: Auto-Redirect Any Folder Path to index.html

πŸš€ Fixing CloudFront "Forbidden" Errors with CloudFront Functions: Auto-Redirect Any Folder Path to index.html

Β·

4 min read

πŸ“Œ Introduction

Have you hosted a static website on AWS CloudFront with an S3 private bucket and faced this issue?

βœ… https://yourdomain.com/random-page/index.html β†’ Works
❌ https://yourdomain.com/random-page β†’ Forbidden (403 Error)
❌ https://yourdomain.com/random-page/ β†’ Forbidden (403 Error)

This happens because CloudFront does not automatically append index.html when accessing directories. But don't worry! In this guide, we’ll troubleshoot the issue and fix it using CloudFront Functionsβ€”without changing your file names.


πŸ› οΈ Understanding the Issue

πŸ” Why does this happen?

AWS S3 is an object storage service, not a traditional web server. Unlike Apache or Nginx, S3 does not recognize directoriesβ€”it only sees files.

  • When you request https://yourdomain.com/random-page, CloudFront searches for an object named exactly random-page, which does not exist.

  • But when you request https://yourdomain.com/random-page/index.html, the file exists in S3, so CloudFront serves it correctly.

  • Unlike traditional web servers, CloudFront does not automatically append index.html to folder paths.

πŸ”Ή Goal: We need to make https://yourdomain.com/ANYTHING and https://yourdomain.com/ANYTHING/ automatically redirect to index.html.


πŸ› οΈ Solution: Fix Routing with a CloudFront Function

The best way to fix this issue is by using CloudFront Functions. These are lightweight, JavaScript-based functions that run at CloudFront Edge Locations.

πŸš€ Why Use CloudFront Functions?

βœ… Fast Execution – Runs at CloudFront Edge, reducing latency
βœ… Cost-Effective – Cheaper than AWS Lambda@Edge
βœ… Scalable – Handles millions of requests per second
βœ… No Changes in S3 Required – Fix the issue at CloudFront level

πŸ”Ή Use Cases for CloudFront Functions:

  • Rewrite URLs dynamically (e.g., auto-append index.html)

  • Redirect HTTP to HTTPS

  • Add security headers

  • Block unwanted traffic

Now, let’s implement the solution! πŸš€


πŸ”Ή Step 1: Create a CloudFront Function

1️⃣ Go to AWS CloudFront Console

  • Open the AWS CloudFront Dashboard

  • Click on Functions β†’ Create function

  • Name it "RewriteToIndexHtml"

  • Click "Create function"

2️⃣ Add the following JavaScript code

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // If the URL does not contain a file extension, append "index.html"
    if (!uri.includes('.') && !uri.endsWith('/')) {
        request.uri += '/index.html';
    } 
    else if (uri.endsWith('/')) {
        request.uri += 'index.html';
    }

    return request;
}

πŸ” Explanation of CloudFront Function Code

This CloudFront Function modifies incoming requests to ensure folder paths correctly serve index.html.

1️⃣ Checks if the URL (uri) has a file extension (.) or ends with /

  • If no file extension and no trailing /, appends "/index.html"

  • If trailing / exists, appends "index.html"

2️⃣ Returns the modified request so CloudFront fetches the correct file from S3.

βœ… Ensures URLs like yourdomain.com/about correctly load yourdomain.com/about/index.html. πŸš€

3️⃣ Save and Publish the Function

  • Click Save

  • Click Publish


πŸ”Ή Step 2: Attach the Function to Your CloudFront Distribution

1️⃣ Go to Your CloudFront Distribution

  • Click on Distributions β†’ Select your CloudFront distribution

  • Go to the Behaviors tab

  • Click Edit on the behavior for your S3 origin

2️⃣ Attach the Function

  • Scroll down to "Function Associations"

  • Under "Viewer Request", select the function you just created (RewriteToIndexHtml)

  • Click Save Changes


πŸ”Ή Step 3: Invalidate CloudFront Cache

Since CloudFront caches content, you need to invalidate the cache to apply the new routing logic.

πŸ”Ή Run this command in AWS CLI:

aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"

Now CloudFront will fetch fresh content and apply the function.


🎯 Final Testing: Does It Work?

User RequestsBefore Fix (403 Error)After Fix (200 OK)
https://yourdomain.com/❌ Forbiddenβœ… /index.html
https://yourdomain.com/random-page❌ Forbiddenβœ… /random-page/index.html
https://yourdomain.com/random-page/❌ Forbiddenβœ… /random-page/index.html
https://yourdomain.com/any-folder-name❌ Forbiddenβœ… /any-folder-name/index.html

πŸš€ Now your website behaves like a normal static site! πŸŽ‰


πŸ“Œ Use Case: When Should You Use This?

πŸ”Ή Hosting a static website with S3 + CloudFront where you need directory-style URLs (/page instead of /page/index.html).
πŸ”Ή Avoiding unnecessary redirects or renaming files in S3.
πŸ”Ή Improving SEO and user experience by allowing clean URLs without .html.
πŸ”Ή Reducing costs by using CloudFront Functions instead of Lambda@Edge.


πŸ’‘ Key Takeaways

βœ… CloudFront does not automatically serve index.html when accessing folder paths.
βœ… S3 is object-based storageβ€”it does not recognize directories, only files.
βœ… A CloudFront Function can rewrite URLs dynamically to fix this issue.
βœ… No need to rename files or change S3 storage structure.
βœ… CloudFront Functions are fast, scalable, and cost-effective compared to Lambda@Edge.


πŸš€ Final Thoughts

This simple fix allows CloudFront to behave like a traditional web server, automatically loading index.html for subpages without renaming files in S3!

If you found this helpful, share this blog and let me know your thoughts in the comments! πŸ’¬πŸš€


✨ Need More AWS & DevOps Tips?

Follow me for more AWS, DevOps, and Cloud solutions! πŸŒπŸš€

Did you find this article valuable?

Support NavyaDevops by becoming a sponsor. Any amount is appreciated!

Β