My server returns the following headers:

Date:Thu, 07 Jul 2011 10:41:57 GMT
Expires:Thu, 01 Jan 1970 00:00:01 GMT
Last-Modified:Thu, 07 Jul 2011 08:06:32 GMT

I want the content I'm serving not to be cached, so I'm looking for a way to return a Last-Modified header that contains the date-time when the request was originated. Something like now()...

3 Answers 3


"I want the content I'm serving not to be cached" : You can turn off If-Modified-Since request header checking with if_modified_since off; directive. if_modified_since doc

And about Last-Modified header: You can turn it off with add_header Last-Modified "";

  • 1
    You can't turn off headers with add_header, you can only add them. From the entry: Note that it just appends a new header entry to the output header list. So you can't use this directive to rewrite existing headers like Server. Use the headers_more module for it.
    – kolbyjack
    Jul 7, 2011 at 14:16
  • I've checked it with curl -D and after adding add_header Last-MOdified ""; to my nginx.conf, Last-Modified header is no longer there in dump file. Jul 7, 2011 at 16:54
  • 1
    Wow, looking at the source, Cache-Control and Last-Modified are special cased and will be set instead of having an extra entry added. It seems the wiki needs to be updated.
    – kolbyjack
    Jul 7, 2011 at 18:03
  • 1
    I was wrong again, Cache-Control is special cased, but it doesn't overwrite, it just has to be added in a special way. Only Last-Modified sets the header instead of adding a new one.
    – kolbyjack
    Jul 7, 2011 at 18:16
  • Good to know, could you point me to a file ? Is it in src/http/ngx_http_header_filter_module.c ? Jul 7, 2011 at 18:33

You may want to make it look like a file is always modified:

add_header Last-Modified $date_gmt;
if_modified_since off;
etag off;

As for the last line, if you really want to hide a true last-modified date, then you must hide the ETag header too since it leaks timestamps.


I've honestly spent a whole day on this and not closer to getting Nginx to play along properly especially with the way Nginx incorrectly formats the Last-Modified: Date header which is not within the RFC's for a Last-Modified header.

I found this solution however which, if you are using PHP, works just fine and can be tweaked as you need. Hope it helps. Just include this at the very top of your .php pages before the rest of your code.

//get the last-modified-date of this very file
//get a unique hash of this file (etag)
$etagFile = md5_file(__FILE__);
//get the HTTP_IF_MODIFIED_SINCE header if set
$ifModifiedSince=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);
//get the HTTP_IF_NONE_MATCH header if set (etag: unique file hash)
$etagHeader=(isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);

//set last-modified header
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $lastModified)." GMT");
//set etag-header
//header("Etag: $etagFile");
header("ETag: \"$etagFile\"");
//make sure caching is turned on
header('Cache-Control: private, must-revalidate, proxy-revalidate, max-age=3600');

//check if page has changed. If not, send 304 and exit
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])==$lastModified || $etagHeader == $etagFile)
       header("HTTP/1.1 304 Not Modified");
       header("Vary: Accept-Encoding");

Then test your site at redbot.org and www.hscripts.com


  1. Added sending the vary header with the 304 not modified response (required)
  2. Modified Cache:Control header max-age can be tweaked to your own needs.
  3. To give credit where it is due, I found the solution here and tweaked it slightly - https://css-tricks.com/snippets/php/intelligent-php-cache-control/

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.