I have nginx and its cache working as expected apart from one minor issue. When a request is made for the first time it hits the origin server, returns a 200 and nginx caches that response. If I make another request I can see from the X-Cache-Status header that the cache has been hit. When I wait a while knowing the cache will have expired I can see nginx hit my origin server doing a conditional GET because I have proxy_cache_revalidate on; defined.
When I check if the resource has changed in my app on the origin server I see it hasn't and return a 304 with a new Expires header. Some may argue why are you returning a new Expires header if the origin server says nothing has changed and you are returning 304. The answer is, the HTTP RFC says that this can be done https://tools.ietf.org/html/rfc7234#section-4.3.4
One thing I have noticed, no matter what headers are I add or modify, when the origin server returns 304 nginx will give a response with the first set of response headers it saw for that resource.
Also if I change the Cache-Control:max-age header value from the first request when I return the 304 response it appears nginx obeys the new value as my resource is cached for that time however the response header value is that of what was given on the first request not the value that I modified on the 304 response. This applies to all subsequent requests if the origin server issues a 304.
I am running nginx version: nginx/1.10.1