{"id":5147,"date":"2026-08-30T08:20:35","date_gmt":"2026-08-29T23:20:35","guid":{"rendered":"https:\/\/donguri3.net\/server-tech\/gsc-sitemap-not-updating-fix-2\/"},"modified":"2026-08-30T08:20:36","modified_gmt":"2026-08-29T23:20:36","slug":"gsc-sitemap-not-updating-fix","status":"publish","type":"post","link":"https:\/\/donguri3.net\/en\/server-tech\/wordpress-blog-seo\/gsc-sitemap-not-updating-fix\/","title":{"rendered":"How to Fix Unupdated Sitemaps in Google Search Console: Improving with Last-Modified and 304 Responses"},"content":{"rendered":"<p>An issue occurred where the sitemap fetch date was not updating in Google Search Console (hereafter GSC), preventing new articles from being reflected in the index.<br \/>The site is operated on a WordPress + OpenLiteSpeed (LiteSpeed Cache plugin) environment. While the parent sitemap (<code>sitemap.xml<\/code>) was being fetched, monthly child sitemaps (e.g., <code>sitemap-posttype-post.202508.xml<\/code>) had not been updated since August 5th.<\/p>\n<p>Since Bing Webmaster Tools was retrieving them normally, I deduced that the conditions related to Google&#8217;s crawling decisions and update detection were not being met.<\/p>\n<hr \/>\n<h2>Objective<\/h2>\n<ul>\n<li>\n<p>Ensure GSC reliably detects updates to child sitemaps<\/p>\n<\/li>\n<li>\n<p>Keep the sitemap fetch date updated and promote the indexing of new pages<\/p>\n<\/li>\n<li>\n<p>Prevent future erroneous caching and missed update detections<\/p>\n<\/li>\n<\/ul>\n<hr \/>\n<h2>Issues Identified Through Investigation<\/h2>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ curl -I https:\/\/donguri3.net\/sitemap-posttype-post.202508.xml\nHTTP\/2 200\netag: &quot;1924cd0be2d2a478d9675f0d7d647bd6&quot;\ncontent-type: application\/xml; charset=UTF-8\nx-robots-tag: noindex, follow\nexpires: Wed, 11 Jan 1984 05:00:00 GMT\ncache-control: no-cache, must-revalidate, max-age=0, no-store, private, no-store\nlink: &amp;amp;lt;https:\/\/donguri3.net\/wp-json\/&amp;amp;gt;; rel=&quot;https:\/\/api.w.org\/&quot;\nvary: Accept-Encoding\nx-litespeed-cache: hit\ndate: Sun, 10 Aug 2025 13:40:14 GMT\nserver: LiteSpeed\nalt-svc: h3=&quot;:443&quot;; ma=2592000, h3-29=&quot;:443&quot;; ma=2592000, h3-Q050=&quot;:443&quot;; ma=2592000, h3-Q046=&quot;:443&quot;; ma=2592000, h3-Q043=&quot;:443&quot;; ma=2592000, quic=&quot;:443&quot;; ma=2592000; v=&quot;43,46&quot;<\/pre>\n<ol>\n<li>\n<p><strong>Missing <code>Last-Modified<\/code> Header<\/strong><\/p>\n<ul>\n<li>\n<p>Google uses <code>Last-Modified<\/code> as a reference for update detection, but it was not included in WordPress&#8217;s output.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Potential ETag Fixation<\/strong><\/p>\n<ul>\n<li>\n<p>Due to LiteSpeed caching and plugin effects, ETags may not change even when the content changes.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Sitemaps Subject to LiteSpeed Cache<\/strong><\/p>\n<ul>\n<li>\n<p>There was a risk that older XML would be returned due to cache hits.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Lack of Support for If-Modified-Since<\/strong><\/p>\n<ul>\n<li>\n<p>Even when Googlebot sends conditional requests, it returns 200 every time instead of 304 Not Modified.<br \/>\u2192 Results in wasteful re-fetches, leading to inefficient crawling.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<hr \/>\n<h2>Solutions<\/h2>\n<h3>1. Exclude Sitemaps from Caching<\/h3>\n<p>In LiteSpeed Cache (LSCWP), go to Cache > Exclude and add the following to &#8220;Do Not Cache URIs&#8221;.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\/sitemap.xml\n\/sitemap-*.xml\n\/sitemap-posttype-*.xml\n\/*sitemap*.xml<\/pre>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\"><\/div>\n<p>Additionally, added bypass rules to <code>.htaccess<\/code> or the OLS VHost Rewrite so that enabling caching in the future will not affect them.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\"># --- Completely bypass Sitemaps (prevent future erroneous caching) ---\nRewriteCond %{REQUEST_URI} &quot;(^\/sitemap\\.xml$|\/sitemap-.*\\.xml$|\/.*sitemap.*\\.xml$)&quot;\nRewriteRule .* - &#x5B;E=cache-control:no-cache,E=cache-disable=1]<\/pre>\n<hr \/>\n<h3>2. Implementing <code>Last-Modified<\/code> and 304 Responses<\/h3>\n<p>In <code>functions.php<\/code>, retrieve the last modified timestamp from the actual child sitemap data (the latest updated article of that month) and set it to <code>Last-Modified<\/code>.<br \/>Furthermore, compare it with <code>If-Modified-Since<\/code>, and if it is identical or newer, return <strong>304 Not Modified<\/strong>.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nadd_action(&#039;init&#039;, function () {\n$req = $_SERVER&#x5B;&#039;REQUEST_URI&#039;] ?? &#039;&#039;;\nif (!preg_match(&#039;#\/(wp-sitemap|sitemap).*\\.xml$#&#039;, $req)) return;\n\n$lm_ts = null;\nif (preg_match(&#039;#\/sitemap-posttype-post\\.(\\d{4})(\\d{2})\\.xml$#&#039;, $req, $m)) {\n$q = new WP_Query(&#x5B;\n&#039;post_type&#039; =&amp;gt; &#039;post&#039;,\n&#039;post_status&#039; =&amp;gt; &#039;publish&#039;,\n&#039;date_query&#039; =&amp;gt; &#x5B;&#x5B;&#039;year&#039; =&amp;gt; (int)$m&#x5B;1], &#039;month&#039; =&amp;gt; (int)$m&#x5B;2]]],\n&#039;orderby&#039; =&amp;gt; &#039;modified&#039;,\n&#039;order&#039; =&amp;gt; &#039;DESC&#039;,\n&#039;posts_per_page&#039; =&amp;gt; 1,\n&#039;no_found_rows&#039; =&amp;gt; true,\n&#039;fields&#039; =&amp;gt; &#039;ids&#039;,\n]);\nif (!is_wp_error($q) &amp;amp;&amp;amp; !empty($q-&amp;gt;posts)) {\n$lm_ts = (int) get_post_modified_time(&#039;U&#039;, true, $q-&amp;gt;posts&#x5B;0]);\n}\nwp_reset_postdata();\n}\nif (!$lm_ts) $lm_ts = time() - 600;\n\n$lm_http = gmdate(&#039;D, d M Y H:i:s&#039;, $lm_ts) . &#039; GMT&#039;;\nheader_remove(&#039;ETag&#039;);\nheader(&#039;Last-Modified: &#039; . $lm_http, true);\nheader(&#039;Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private&#039;, true);\n\n$ims_raw = $_SERVER&#x5B;&#039;HTTP_IF_MODIFIED_SINCE&#039;] ?? &#039;&#039;;\n$ims_ts = $ims_raw ? strtotime($ims_raw) : false;\n\nif ($ims_ts !== false &amp;amp;&amp;amp; $ims_ts &amp;gt;= $lm_ts) {\nstatus_header(304);\nhttp_response_code(304);\nif (php_sapi_name() === &#039;cgi-fcgi&#039;) header(&#039;Status: 304 Not Modified&#039;, true);\nheader(&#039;Content-Length: 0&#039;);\nexit;\n}\n}, 0);<\/pre>\n<hr \/>\n<h3>3. Operation Verification<\/h3>\n<h4>Header Check<\/h4>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">curl -I https:\/\/blog.example.com\/sitemap-posttype-post.202508.xml<\/pre>\n<ul>\n<li>\n<p><code>Last-Modified<\/code> matches the actual last modification time<\/p>\n<\/li>\n<li>\n<p>No <code>ETag<\/code><\/p>\n<\/li>\n<li>\n<p><code>Cache-Control<\/code> set to no-cache<\/p>\n<\/li>\n<\/ul>\n<h4>304 Response Check<\/h4>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">LM=&quot;Sat, 02 Aug 2025 06:05:23 GMT&quot;\ncurl -I -H &quot;If-Modified-Since: $LM&quot; https:\/\/blog.example.com\/sitemap-posttype-post.202508.xml<\/pre>\n<p>\u2192 <code>HTTP\/2 304 Not Modified<\/code><\/p>\n<hr \/>\n<h2>Results<\/h2>\n<p>After the fix, I <strong>resubmitted<\/strong> the child sitemap whose fetching had stalled in GSC. After a short while, it displayed as &#8220;Success,&#8221; and the last fetch date was updated.<br \/>Subsequently, new articles have been smoothly indexed as well.<\/p>\n<hr \/>\n<h2>Summary<\/h2>\n<ul>\n<li>\n<p><strong>The <code>Last-Modified<\/code> header is crucial for update detection<\/strong><\/p>\n<\/li>\n<li>\n<p><strong>Cache exclusion settings are mandatory<\/strong> (especially in LiteSpeed environments)<\/p>\n<\/li>\n<li>\n<p><strong>304 responses reduce wasteful crawls and improve update detection accuracy<\/strong><\/p>\n<\/li>\n<li>\n<p>When the &#8220;Last read&#8221; date in GSC does not update, review both server and application caching and header settings<\/p>\n<\/li>\n<\/ul>\n<p>With this response, Google&#8217;s crawling stabilized, and indexing speed improved.<br \/>If you are facing a similar issue where sitemaps are not updating in GSC, be sure to check your <code>Last-Modified<\/code> and cache control settings.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An issue occurred where the sitemap fetch date was not updating in Google Search Console (hereafter GSC), prev [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":1952,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/donguri3.net\/?p=1950","footnotes":""},"categories":[1166],"tags":[193,52,15,13,14,196,61,10,194],"class_list":["post-5147","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress-blog-seo","tag-google-search-console","tag-https","tag-litespeed","tag-ols","tag-openlitespeed","tag-seo","tag-wordpress","tag-server","tag-194","en-US"],"_links":{"self":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5147","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/comments?post=5147"}],"version-history":[{"count":1,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5147\/revisions"}],"predecessor-version":[{"id":5150,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5147\/revisions\/5150"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media\/1952"}],"wp:attachment":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media?parent=5147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/categories?post=5147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/tags?post=5147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}