Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve "x-cache: Error from cloudfront" on SPA

We are having issues trying to make working a SPA with a client router (react router). We are using the concept of have a DOMAIN -> CDN (CloudFront) -> S3 for serving our static files.

We have configured the S3 for serving static files. The CDN are configured to have the origin from the S3 and we have configured custom error pages to catch errors:

enter image description here

with this configuration we can catch errors like this:

https://www.example.com/custom-url

The CDN will redirect all the 404/403 errors to the main index.html and react router will get the correct routing.

We have working our site, and the client router is working fine, but we have a problem with the response of our CDN with x-cache: Error from cloudfront:

enter image description here

If we access to the main url https://www.example.com without any query param (not query string) all works fine.

How can I solved this problem and make that all my dynamic URLs work?

Thanks.

like image 208
chemitaxis Avatar asked Dec 03 '19 15:12

chemitaxis


People also ask

How do I resolve X-cache error from CloudFront?

If the X-Cache header is "Miss from cloudfront," then the request was retrieved from the origin and wasn't served by the cache. Review the Cache-Control header in the response. If the value for Cache-Control is "no-store," then the header is directing CloudFront to not cache the response.

What is X-cache miss from CloudFront?

Resolution. CloudFront returns "X-Cache:Miss from cloudfront" when the request is sent to the origin. CloudFront returns "X-Cache:Hit from cloudfront" when requests are served from the closest edge location. "Miss" requests might be slower to load because of the additional step of forwarding to the origin.

How do I bypass CloudFront cache?

Configuration on the origin On your custom origin web server application, add Cache-Control no-cache, no-store, or private directives to the objects that you don't want CloudFront to cache. Or, add Expires directives to the objects that you don't want CloudFront to cache.


2 Answers

When you visit http://mywebsite.com the request will hit the index.html file in S3. Then you might click a button and go to http://mywebsite.com/stats which is an internal route of your SPA app. Thus, it will not trigger any backend request.

But if you reload the page, http://mywebsite.com/stats will be sent to S3 as your browser does not know that you are running an SPA frontend.

S3 will return 403 error with index.html and Cloudfront will send you the error.

Solution is using an edge lambda function in Cloudfront. Here an example:

const path = require('path')

exports.handler = (evt, ctx, cb) => {
    const {request} = evt.Records[0].cf

    if (!path.extname(request.uri)) {
        request.uri = '/index.html'
    }

    cb(null, request)
}

Source: https://hackernoon.com/how-to-host-a-single-page-application-with-aws-cloudfront-and-lambda-edge-39ce7b036da2

like image 175
jackops Avatar answered Oct 20 '22 10:10

jackops


Amazon CloudFront can get tricky with its configuration and debugging an error code - to trace it back to its root cause can take several hours. However, you might want to make the following checks before you get into the logs.


Bucket Name!

The bucket names should match the names of the website that you are hosting.

For instance, to host your-domain.com website on Amazon S3, you would create a bucket named your-domain.com.

To host a website under www.your-domain.com, you would name the bucket www.your-domain.com.

Its a best practice, to create buckets for both your-domain.com and www.your-domain.com.

Use the existing logic in your settings/configuration for any one of these buckets and use it to serve the static website. Use the other bucket to redirect the request to the original bucket.

Bucket Redirection Settings

Honestly, this wouldn't be causing you the trouble since you've integrated your system with Amazon CloudFront, which can be configured to use an Amazon S3 bucket of any name.

With Amazon CloudFront, users that visit your domain will directly fetch data from the CloudFront distribution which in turn caches contents from our S3 bucket.


Configuring the distribution's Origin Settings.

While creating a distribution with Amazon CloudFront make note of the associated Amazon S3 endpoint with the Origin Domain Name. Make sure to use the web site endpoint and NOT the REST endpoint. Don't use the endpoint auto-suggested by CloudFront.

There is a difference in the behavior as explained in the Amazon Web Services official documentation


4XX Error Code!

From your console logs, it suggests distribution instance is trying to access a forbidden element, page or resource and hence the 403 status code.

While the 404 is merely a result of page not found. However, after the error redirection - as handled in your configuration, the user is redirected back to index.html where it encounters the 403.

More information on - How CloudFront Processes and Caches HTTP 4xx and 5xx Status Codes from Your Origin


Other usual suspects include Caching Configurations for Amazon CloudFront distribution, AWS Route53 settings, and Amazon Certificate Manager.

As mentioned in the beginning it can get quite perplexing while tracking such errors. Let us know if the above helps. Also, I would really appreciate it if you could post updates on your investigations and findings.

Thanks for the read.

like image 28
Ronnie Avatar answered Oct 20 '22 12:10

Ronnie