We are using CloudFront for our static assets but also wanted to allow for Gzip. We set up a new distribution with a custom origin pointing back to our application servers which are behind a elastic load balancer. We manually keep the files in sync across the cluster and update them when we publish.

However, with this set up, we get nothing but Miss and RefreshHits from CloudFront, which so far has defeated the purpose. Is there any additional settings in order to use an ELB as your custom origin? In the docs, it references this as a viable solution.

It appears when we point the distribution to a single server in our production cluster, cloudfront properly caches our assets.

Is it possible that the sticky sessions cookie and the subsequent header that gets added by it could be an issue?

Cache-Control: no-cache="set-cookie" //Added by load balancer

Any ideas?

FYI - currently, we have our custom origin pointing to a single EC2 instance, so caching is working correctly - in case you try to curl the file below.

Example headers: curl -I http://static.quick-cdn.com/css/9850999.css

HTTP/1.0 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=3700
Cache-Control: no-cache="set-cookie"
Content-Length: 23038
Content-Type: text/css
Date: Thu, 12 Apr 2012 23:03:52 GMT
Last-Modified: Thu, 12 Apr 2012 23:00:14 GMT
Server: Apache/2.2.17 (Ubuntu)
Vary: Accept-Encoding
X-Cache: RefreshHit from cloudfront
X-Amz-Cf-Id: K_q7Zy3_jdzlEJ85ukELVtdx1GmuXqApAbZZ7G0fPt0mxRMqPKX5pQ==,RzJmPku-rEIO9WlvuSoKa8hiAaR3dLk5KC4cQMWWrf_MDhmjWe8n6A==
Via: 1.0 28c34f9fbf559a21ee16594849e4fc9c.cloudfront.net (CloudFront)
Connection: close

It's possible that CloudFront doesn't handle multiple headers with the same name correctly and isn't seeing your max-age directive. According to this CloudFront does use the Expires header if present, so try getting your origin server to set that instead (preferably relative to the request time). For Apache I think you want something like this with mod_expires:

ExpiresDefault "access plus 1 hour"
  • Yeah - we had thought something similar. I'll play around with getting the Expires header set. we actually have mod_expires installed and configured, need to take a look as to why the Expires header isnt passing.
    – kmfk
    Apr 16 '12 at 17:26
  • 1
    Just as an update - tried it with the Expires header - same results. I have an open thread on the AWS boards - figured Amazon's team might of have some insight - so far, no dice.
    – kmfk
    Apr 16 '12 at 21:46
  • @kmfk You are correct. I have been “proof of concept”ing CloudFront for a few unique servers in my control, and the thing I have learned is Expires headers have 100% no value with CloudFront with regards to edge servers picking up on changes in content. It all boils down to “Cache-Control” which means you need to get a handle on that header specifically to affect any change. Which is annoying. Because it ultimately means the flexibility of “Expires” headers is only valid to end browsers in this setup. Jan 11 '14 at 15:55

When using sticky sessions on the ELB, the load balancer will add the following two headers to response: Set-Cookie (with the AWSELB cookie) and Cache-Control: no-cache="set-cookie".

If the min-ttl on your CF Distro is 0 (which is now the default value), CloudFront will use the no-cache directive. An Amazon rep linked me this: w3.org - RFC2616.

The following from the no-cache section applies:

If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching. However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server

However, from my experience, CloudFront always revalidates the object if the no-cache directive is set. I believe, they should actually just omit the Set-Cookie header as specified in the no-cache to begin with.

The quick fix was creating a new CF Distro and manually specifying a min-ttl greater than 0, which seems to override the no-cache directive. You need to use the API or a 3rd party program to do, as the AWS Console does not allow you to modify the min-ttl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.