How to solve CORS IE font issues with Amazon Cloudfront

Written by Adrian Holovaty on July 25, 2014

I've been wrestling with this for a while, and I finally found a fix! Here's a quick post for developers searching for the solution...

The problem

If you use Amazon Cloudfront to serve web fonts (.ttf, .woff, .eot, etc.) from your Amazon S3 bucket (as I do for Soundslice), Internet Explorer will likely refuse to load the fonts, giving this error message:

CSS3117: @font-face failed cross-origin request. Resource access is restricted.

This happens because your media files on Cloudfront are on a separate domain than your site, and Internet Explorer doesn't like the cross-domain requests for security reasons.

The solution

The solution is to get CORS working with Amazon S3, then to get Cloudfront to forward the appropriate headers. Amazon only recently made this possible (less than a month ago, as of this writing), so there's not a lot of documentation on it.

Here's how, step by step:

First, go to the web interface for your S3 bucket, click "Properties," then "Permissions," then "Edit CORS Configuration." Enter this and save it:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
    </CORSRule>
</CORSConfiguration>

Note: if you're particularly security-conscious, you may want to lock this down more. In this example, I'm allowing access to all files from any origin. Here's a post with an example of a locked-down version of the S3 CORS settings.

Next, go to the web interface for your Cloudfront "distribution," and click "Distribution Settings," then the "Behaviors" tab. Select the behavior (assuming you have only one) and click "Edit."

For "Forward Headers," change it from "None (Improves Caching)" to "Whitelist." A "Whitelist Headers" section will appear. Add "Origin" to this list. This tells Cloudfront to take the "Origin" header into account when caching.

Here's a step that I'm not certain is necessary, but I did it anyway: next to "Allowed HTTP Methods," select "GET, HEAD, PUT, POST, PATCH, DELETE, OPTIONS" instead of "GET, HEAD".

Finally, rename your font files for good measure, so that Cloudfront treats them as new files. I did all of the above steps and was still getting the IE error, but when I renamed the font files, it started working. Cloudfront is really good at caching. :-)

That's it! Enjoy your fully working web fonts in IE, served by S3/Cloudfront.

UPDATE, Aug. 28, 2014: Google Chrome now requires this CORS stuff on fonts, as of version 37.0.2062.94. And here's another thing I discovered the hard way: rather than using protocol-relative URLs for your fonts, pick one of either HTTP or HTTPS and stick with it. (I recommend HTTPS.) The reason is, if you request a font via HTTP, then Cloudfront will cache it as HTTP; any subsequent CORS request to the HTTPS version will try to use the HTTP version and will fail. (Source.)

Post a comment