I'm trying to get Cache-Control working on Nginx for assets on my server and it is not taking as expected. Here is my server config for Nginx.

Everything but Cache-Control is working.

Server Blocks

server {
   listen 80;
   server_name www.example.com;
   rewrite ^ https://$server_name$request_uri? permanent;

server {
   listen 80;
   server_name example.com;
   rewrite ^ https://www.$server_name$request_uri? permanent;

server {
   listen 443 ssl;
   server_name default;
   root /app/public;

   ssl_certificate /etc/nginx/ssl/default/crt/server.crt;
   ssl_certificate_key /etc/nginx/ssl/default/crt/server.key;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   index index.html index.htm index.php;
   charset utf-8;
   add_header "X-UA-Compatible" "IE=Edge,chrome=1";

   location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
       expires 1d;
       access_log off;
       add_header Pragma public;
       add_header Cache-Control "public, max-age=86400";
       add_header X-Asset "yes";

   location / {
      try_files $uri $uri/ /index.php?$query_string;

   location = /favicon.ico { access_log off; log_not_found off; }
   location = /robots.txt { access_log off; log_not_found off; }
   access_log off;
   error_log /var/log/nginx/default-error.log error;

   error_page 404 /index.php;
   location ~ \.php$ {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
      fastcgi_index index.php;
      include fastcgi_params;

   location ~ /\.ht {
      deny all;

Here is my server's response for https://www.example.com/icons/facebook.png:

Cache-Control:public, max-age=120
Date:Tue, 04 Oct 2016 14:46:26 GMT
Last-Modified:Mon, 03 Oct 2016 18:18:37 GMT

The max-age is 120 where I am expecting 86400 and there is no custom X-Asset header too.

HTTP Block

The /etc/nginx/conf.d/ folder is empty.

http {

    # Basic Settings

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # SSL Settings

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    # Logging Settings

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # Gzip Settings

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 5;
    # gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # Virtual Host Configs

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
  • also, do you really need "add_header Pragma public;" ? it's never been used properly and it has since been deprecated – pcarvalho Nov 25 '16 at 6:47

Is your origin sending back a Cache-Control header? Or is this one of the files that would be served directly from file system.

If so, perhaps you just have not reloaded nginx after the change? sudo nginx -s reload

Separate from your direct question, but just a note that the line:

add_header "X-UA-Compatible" "IE=Edge,chrome=1";

won't apply on any location that contains it's own add_header directive (you can see this in your pasted output).

  • I have restarted Nginx. Should I reload the config or does restart do the same thing? – Kevin Oct 4 '16 at 16:03
  • The facebook.png file is being returned from the server as expected it is just not loading the correct cache-control header. – Kevin Oct 4 '16 at 16:04
  • I just added a custom header and it is not showing up as well. I'm wondering if my location regex is bad but I'm not seeing it. – Kevin Oct 4 '16 at 16:34
  • Well the question is whether the Cache-Control header is coming back from the original server (from fastcgi) or something. If your intent is to override then you will need to hide it from the original response to be able to re-add. – Joshua DeWald Oct 4 '16 at 21:47
  • What do you mean by "original server"? Nginx, assets, and application code are all on the same server. Just for clarity, my main goal is to have the browsers cache assets not Nginx. I'm not using Nginx as a proxy for caching. Also, are you saying the fastcgi gateway might be adding headers and looping back to Nginx? I have looked through all other configs and no Cache-Control headers are being set by Nginx. – Kevin Oct 5 '16 at 18:14

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.