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

Navya ANavya A
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! πŸŒπŸš€

0
Subscribe to my newsletter

Read articles from Navya A directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Navya A
Navya A

πŸ‘‹ Welcome to my Hashnode profile! I'm a passionate technologist with expertise in AWS, DevOps, Kubernetes, Terraform, Datree, and various cloud technologies. Here's a glimpse into what I bring to the table: 🌟 Cloud Aficionado: I thrive in the world of cloud technologies, particularly AWS. From architecting scalable infrastructure to optimizing cost efficiency, I love diving deep into the AWS ecosystem and crafting robust solutions. πŸš€ DevOps Champion: As a DevOps enthusiast, I embrace the culture of collaboration and continuous improvement. I specialize in streamlining development workflows, implementing CI/CD pipelines, and automating infrastructure deployment using modern tools like Kubernetes. β›΅ Kubernetes Navigator: Navigating the seas of containerization is my forte. With a solid grasp on Kubernetes, I orchestrate containerized applications, manage deployments, and ensure seamless scalability while maximizing resource utilization. πŸ—οΈ Terraform Magician: Building infrastructure as code is where I excel. With Terraform, I conjure up infrastructure blueprints, define infrastructure-as-code, and provision resources across multiple cloud platforms, ensuring consistent and reproducible deployments. 🌳 Datree Guardian: In my quest for secure and compliant code, I leverage Datree to enforce best practices and prevent misconfigurations. I'm passionate about maintaining code quality, security, and reliability in every project I undertake. 🌐 Cloud Explorer: The ever-evolving cloud landscape fascinates me, and I'm constantly exploring new technologies and trends. From serverless architectures to big data analytics, I'm eager to stay ahead of the curve and help you harness the full potential of the cloud. Whether you need assistance in designing scalable architectures, optimizing your infrastructure, or enhancing your DevOps practices, I'm here to collaborate and share my knowledge. Let's embark on a journey together, where we leverage cutting-edge technologies to build robust and efficient solutions in the cloud! πŸš€πŸ’»