Netlify-cli not updating permalinks?

I have a hugo site that I build locally and push to netlify with cli.

I noticed that when I change permalinks, netlify does not seem to refresh the site unless I clear browser cache.

  1. Build locally rm -rf public && npx netlify build
  2. Push to netlify npx netlify deploy -p
  3. Verify in netlify admin that the latest push has been published
  4. Navigate to the site and notice permalinks that where changed still use the old permalinks
  5. Open Chrome inspector with “disable cache” checked and refresh the page and links on that page are now using the new permalinks

Old permalinks: x-nf-request-id: e74d8cff-6c64-4da6-aff3-4062127baa28-10495006
New permalinks (after cache flush): x-nf-request-id: 7a6028bc-45af-4739-b681-f82e392fdab8-17522745

Old permalinks: x-nf-request-id: 3e01daad-6e33-45d0-80cb-bb238265fbb0-13629186
New permalinks (after cache flush): x-nf-request-id: c7875543-11f1-4c29-bab8-c8eb5c9401a4-14094790

Changing page content (like a paragraph) does not seem to have the same issue. I only have an issue when changing URLs. Global elements, such as the main menu have the incorrect permalinks on every page unless I clear all browser cache for the domain or for each individual page.

I should note that the sitemap file is updating the permalinks correctly and locally all permalinks update fine. This caching issue only happens on netlify.

I’ve also checked the issue on other devices where I haven’t gone to the site in a few days and they too have the issue with incorrect permalinks still being used.

Why is it that regular page content is updating without any issue, but permalinks won’t update without cache purges?

I add a header of Cache-Control: public, max-age=31536000

When I change this to Cache-Control: public, max-age=0 it seems to help prevent permalinks being cached.

But, why would regular content like paragraphs update without issue with max-age=31536000 but permalinks refuse to update without clearing cache?

Digging into this a bit more.

Cache-Control: public, max-age=31536000 - content updates without issue but permalinks do not

Cache-Control: public, max-age=0 - both content and permalinks update without issue but caching doesn’t happen

Cache-Control: public, max-age=31536000, must-revalidate - content and permalinks update. If there is no change, content is cached but headers are revalidated. If there is a change, document is fetched

I guess my question at this point is, why does Cache-Control: public, max-age=31536000 allow the content to update when there is a change but not when there is a permalink change? Why are links being treated differently and the updated document not being fetched without clearing browser cache manually?

Hi, @simplerethink. Because that is what you are telling the browser to do with that header. There is more about how the cache-control header works here:

We do not recommend changing our default cache-control headers are our current cache invalidation strategy works best with them unchanged. There is a detailed write up about how caching works at Netlify here:

To summarize, you were telling the browser just to use the cached version so it did. If you stop doing that, it won’t.

If there are other questions about this, please let us know.

@luke - I’d generally agree with you, but there doesn’t seem to be consistency. If I’m telling the browser to cache the content, then why is the content updating when I change something like a paragraph of text, but not updating when I update permalinks? Content is content, right? Whether a link or page text. But for some reason, the two are being treated differently.

Hey there, @simplerethink

Thanks for starting this thread! Looks like @luke is already giving you some good guidance here. I also encourage you to take a look at our CLI repo and see if there is an issue related to this that is already open. If there isn’t, please do file an issue.


Hi, @simplerethink, if you think they are caching errors I can check. First, I need to know exactly what HTTP request to examine though.

The simplest way to do this is to send us the x-nf-request-id header which we send with every HTTP response.

There more information about this header here:

If that header isn’t available for any reason, please send the information it replaces (or as many of these details as possible). Those details are:

  • the complete URL requested
  • the IP address for the system making the request
  • the IP address for the ADN node that responded
  • the day and time of the request (plus the timezone the time is in)

If you tell us that information I can see exactly what version of a resourced was served. If it is the incorrect version, we will find out why.