seo

“Sitemap Could Not Be Read”: How To Diagnose And Fix It On WordPress

Google Search Console sitemap could not be read error — WordPress 404 diagnostic

A step-by-step field guide to the Search Console error that looks like a plugin fault, is usually a routing fault, and almost always hides other problems underneath.

You open Google Search Console on an ordinary morning. Nothing was deployed. Nobody touched the server. The site loads perfectly in your browser. And the Sitemaps report says this:

Sitemap could not be read

General HTTP error

1 instance

HTTP Error: 404

Underneath it, a list of child sitemaps that Google says it did read, each carrying an error of its own. So Google is telling you it both could and could not read your sitemap.

That contradiction is the first clue, and almost everyone misreads it.

This is the sequence I follow on a WordPress site showing this error, with the traps marked and the commands included. It takes about an hour if you work in order, and considerably longer if you start by changing settings.

What the error actually means

A sitemap tells Google which URLs on your site matter. On WordPress with an SEO plugin, you do not have one sitemap — you have several, arranged in a tree:

/sitemap_index.xml        ← the index; lists the others

  ├─ /page-sitemap.xml       your pages

  ├─ /post-sitemap.xml       your posts

  ├─ /category-sitemap.xml   category archives

  └─ /author-sitemap.xml     author archives

These are virtual files. Nothing exists on disk. The plugin registers rewrite rules that map those URLs to generated XML output, and WordPress serves them on request.

Which means each one can fail independently. The index can 404 while a child serves perfectly. That is exactly what the contradictory report is describing, and it is why the first move is not to fix anything.

Why you cannot leave this: When the index 404s, Google’s last interaction with your site’s map of itself was a failure. It does not retry aggressively — on a site without much authority, it may not retry for weeks. Meanwhile, every page you publish depends on internal links alone to be found.

Step 1: Test every sitemap URL individually

Open each one in a private window. Not all at once, not assuming they share a fate. One at a time, and write down what each returns.

Test these

https://www.example.com/sitemap_index.xml

https://www.example.com/page-sitemap.xml

https://www.example.com/post-sitemap.xml

https://www.example.com/category-sitemap.xml

https://www.example.com/author-sitemap.xml

Rank Math XML sitemap index showing post and page sitemaps

On the site I worked through, the results looked like this:

URLResultMeaning
/sitemap_index.xml404Real fault
/page-sitemap.xml200 — 32 URLsHealthy
/post-sitemap.xml404Real fault
/category-sitemap.xml404Expected — removed on purpose
/author-sitemap.xml404Expected — removed on purpose

That table is the entire diagnosis, and it does two things at once.

One child sitemap returning 200 proves the plugin’s sitemap engine works. In a single step, that rules out a broken plugin, a robots.txt block, and a server misconfiguration, are three things people commonly spend a day on.

And two of those 404s were correct. They had been removed deliberately an hour earlier. If you treat five URLs as one unit, you cannot tell a fault from a success, and you will fix something that was never broken.

The habit to build
Never diagnose a list. Diagnose each item. This applies well beyond sitemaps. It is the difference between debugging and guessing.

Step 2: Read the column nobody looks at

Before touching the sitemap, open Indexing → Pages and look at the pages Google is not indexing. For each URL, there is a last-crawled value, and it is the most informative field in the entire report:

Last crawled:   N/A

N/A does not mean Google fetched the page and judged it thin. It means Google never went at all.

That single distinction changes what you are dealing with:

  • A date, plus “Crawled — currently not indexed”: Google fetched the page and decided against indexing it. That is a content and duplication problem.
  • N/A, plus “Discovered — currently not indexed”: Google knows the URL exists and has not bothered. That is a crawl-priority problem, which can be internal linking, sitemap health, and authority.

These have opposite fixes. Rewriting good pages because you read the wrong column is a common and expensive mistake.

Step 3: Tell a routing fault from a missing file

Look carefully at what the 404 actually looks like in your browser.

What you seeWhat it means
Your theme’s styled 404 pageWordPress handled the request and found no matching route — a rewrite-rule fault
A bare server 404 (Apache/LiteSpeed default)The request never reached WordPress — a file, server, or .htaccess issue
An XML parse errorThe sitemap is generating but producing malformed output — usually a plugin conflict
A redirect to somewhere elseA redirect rule is intercepting the URL — check your redirection plugin

If you are seeing your own 404 template, the file is not missing. The routing is. That is the common case, and the fix takes three seconds.

The fix: flush the rewrite rules

WordPress routes every request through a table of rewrite rules stored in the database. When that table is stale or partially written — after a migration, a plugin update, a permalink change, or sometimes for no visible reason — some rules resolve, and others do not.

The fix

WordPress Admin

  → Settings

  → Permalinks

  → Save Changes        (change nothing — just save)

Saving that screen forces WordPress to regenerate the entire rewrite table. It changes no content and no settings. It resolves the majority of virtual-file 404s on WordPress.

The command-line equivalent

WP-CLI

wp rewrite flush –hard

# then confirm the sitemap rules are registered

wp rewrite list | grep sitemap

In PHP, if you need it programmatically

PHP

// Expensive. Never call this on every page load.

// Run it once, from WP-CLI or a one-off admin action.

flush_rewrite_rules();

Order of operations

  1. Flush the permalinks (Settings → Permalinks → Save Changes).
  2. Confirm the affected post type is still enabled in your SEO plugin’s sitemap settings — rule out an accidental change of your own.
  3. Purge the full page cache. On LiteSpeed: LiteSpeed Cache → Toolbox → Purge All.
  4. Retest every sitemap URL individually, in a private window.
  5. Only when all return 200, resubmit the index in Search Console.
Cache is always the first suspect
On LiteSpeed, Cloudflare, or any full-page cache, assume stale cache before assuming a code fault. “Nothing changed after I re-uploaded” is a cache statement far more often than a deployment statement.

If it still 404s

  • Check .htaccess for a leftover rewrite rule from a previous SEO plugin pointing sitemap URLs at a file that no longer exists.
  • Check your redirection plugin for a rule matching .xml or sitemap.
  • Deactivate other plugins one at a time — security and caching plugins are the usual culprits.
  • Confirm the sitemap module itself is enabled in your SEO plugin’s dashboard.

While you are in there: four things worth checking

Chasing a sitemap fault means auditing templates, plugin settings, and the web root — places nobody looks during normal work. Four things came out of that audit, and every one was costing more than the sitemap was.

1. A fifth of the sitemap was taxonomy pages

The category sitemap held 11 URLs, and the author sitemap held 1. Twelve of 57 submitted URLs — 21% — were archive pages WordPress generates automatically.

Twelve articles spread across twelve categories means most category archives contain exactly one post and are a near-duplicate of it. An author archive on a single-author blog duplicates the blog index outright.

Google is right to refuse them. You are asking it to spend crawl budget on pages you never wanted indexed.

Rank Math

Rank Math → Titles & Meta → Categories

   Category Archives Robots Meta : ON   (switch off “Default” first)

   ☑ No Index    ☐ Index    ☑ Follow

Rank Math → Titles & Meta → Authors

   Author Archives : OFF

Rank Math → Sitemap Settings → Taxonomies → Categories

   Include in Sitemap : OFF

   (check Tags is OFF too)

Rank Math category archives robots meta set to No Index
The setting people miss
Noindex and sitemap inclusion are two separate settings. A noindexed page still sitting in your sitemap is the worst combination — you are asking Google to fetch something you have told it not to index. Turn off both.

Verify it landed. View source on any category archive and look for:

<meta name="robots" content="follow, noindex"/>

Do not delete the categories

Categories stay useful for readers and for how the blog is organised. Deleting them unassigns every post. You are suppressing the archive pages they generate, not the taxonomy itself — keep the filter links on your blog index for humans.

2. The blog was structurally orphaned

This is the one that matters most, and it is invisible unless you go looking.

Plenty of modern themes draw the header and footer with JavaScript into empty mount points. The server sends this:

What the server actually sends

<div id="site-header"></div>
<div id="site-footer"></div>

Google renders JavaScript, so the visible navigation is not invisible to it. But rendering is a deferred second pass. On a site with limited crawl budget, links that only exist after render get discovered far more slowly than links in the raw HTML. Well-built themes compensate with a plain fallback copy of the navigation.

On this site, twenty-seven page templates carried that fallback. Three did not: the blog index, the single-post template, and the archive template.

TemplateCoversNav in HTMLFooter in HTML
page templates27 pagesYesYes
home.phpBlog indexNoNo
single.phpEvery articleNoNo
archive.phpCategory archivesNoNo

The consequence: every article shipped raw HTML containing the article, a breadcrumb, and no other links at all. No navigation. No footer. No route to anywhere else on the site, and nothing to indicate the page belonged to a site.

That is precisely what “Discovered — currently not indexed” looks like from the inside.

How to check your own site in thirty seconds

  1. Open any blog article in a private window.
  2. Press Ctrl+U for view-source — the raw HTML, not the inspector, which shows the rendered DOM.
  3. Ctrl+F for one of your navigation labels, or for “noscript”.
  4. If your navigation links are not in that source, the page is relying entirely on render-time discovery.
View-source, not Inspect
The browser inspector shows the DOM after JavaScript has run, so a JS-rendered nav looks perfectly present there. View-source shows what the server actually sent. For this check, only view-source tells you the truth.

The fix

Add the fallback once, centrally, in the functions the uncovered templates already call — not pasted into each template:

functions.php — the helper

/**
 * Crawlable primary navigation.
 *
 * The visible header is drawn by JS into #site-header, so it does not
 * appear in server-rendered HTML. This mirrors it for crawlers.
 * Links only. Never content. If a link changes in the JS header it
 * must change here too, or the two sources drift apart.
 */
function xyz_nav_fallback() {
?>
<noscript>
<nav aria-label="Primary">
<ul>
<li><a href="<?php echo esc_url( home_url( '/' ) ); ?>">Home</a></li>
<li><a href="<?php echo esc_url( home_url( '/services/' ) ); ?>">Services</a></li>
<li><a href="<?php echo esc_url( home_url( '/showcase/' ) ); ?>">Showcase</a></li>
<li><a href="<?php echo esc_url( home_url( '/blog/' ) ); ?>">Blog</a></li>
<li><a href="<?php echo esc_url( home_url( '/about/' ) ); ?>">About</a></li>
<li><a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>">Contact</a></li>
</ul>
</nav>
</noscript>
<?php
}

functions.php — wired in once

function xyz_chrome_open() {
?>
<div id="site-header"></div>
<?php
xyz_nav_fallback();          // <-- added
}
 
function xyz_chrome_close() {
?>
<div id="site-footer"></div>
<?php
xyz_footer_fallback();       // <-- added
}
Patch centrally, not per file
All three uncovered templates already called these two functions, so one edit fixed the blog index, every article, and the archives at once. If you find yourself pasting the same block into ten files, you are editing at the wrong level.

Verify by uploading, purging the cache, then view-source on any article and searching for “noscript”. You want the nav list near the top and the footer block near the bottom.

3. A page serving no meta description

The blog index was serving this:

<title>Blog - Example Site</title>
<meta name="description" content="Blog -"/>
<meta property="og:description" content="Blog -"/>

Six characters and a trailing hyphen, and a 27-character title using none of its 60-character budget on anything a person would actually search for.

Worth checking on bilingual sites in particular: the French version of the same page had a properly written 140-character description. The translation had been done carefully, and the English left on autopilot. That asymmetry is common.

The WordPress trap that costs hours
When a page is assigned as your Posts page under Settings → Reading, WordPress stops treating it as a normal page. Your SEO plugin’s snippet editor on that page has no effect — you can type into it, save, watch it store your text, and the front end never changes. The setting lives on a different screen entirely. If an edit refuses to take, check whether the page has a special role assigned in Reading Settings.

4. Publicly readable source code

Three files were sitting in the theme directory:

functions.php bak

inc-subscribe.php bak

templates/booking.php bak

A file ending in “.php bak” is not executed by PHP. The server treats it as plain text and serves it. Anyone requesting that URL receives the complete source of your functions file.

How it is retrieved

https://example.com/wp-content/themes/child/functions.php%20bak

Two rules worth adopting
Backups never live in the web root — download them, or store them above public_html. And note that extracting a zip over an existing folder overwrites and adds files but never deletes: stale files survive deployment, so clean them by hand.

Search your theme and plugin directories for files ending in .bak, .old, .save, .orig, .txt, and “ bak”. Delete them from the server.

The last check, and the one most audits skip

With the sitemap serving, the taxonomy suppressed, the blog reconnected, and the metadata corrected, run a live crawlability test:

Search Console → URL Inspection

  → paste the URL

  → TEST LIVE URL      (not “View crawled page”)

This fetches your server right now, as Googlebot, rather than showing you a cached result. It answers a question nothing else does:

  • Fails or times out → server-side. Googlebot is being blocked or throttled by a firewall, security plugin or cache layer. Fixable, and worth fixing immediately.
  • Returns “URL is available to Google” → your server and markup are fine. Google is choosing not to spend crawl budget on you.

If it is the second, there is one more report to open, and it is the one that actually predicts whether any of this work will show up in rankings:

Search Console → Links → Top linking sites

Your referring domains. How many other websites point at yours, and who they are.

The honest conclusion
Technical SEO removes obstacles. It does not create authority. Those are two different jobs, and only one of them can be finished in an afternoon. A site can be technically flawless and still go nowhere, and the reason is almost always sitting in that report.

There is a second thing worth reading in it. The Links report also shows which of your pages Google considers most internally linked. If those are URLs from a previous version of your site — pages that no longer exist in that form — Google’s map of your site is out of date, and no amount of new content will rank until it recrawls.

That gives you a progress signal that moves well before traffic does. When the internal-links report starts naming your current URLs, the recrawl has genuinely landed.

The full checklist

#ActionWhere
1Test every sitemap URL individually in a private windowBrowser
2Check “Last crawled” on unindexed URLs — N/A means never fetchedSearch Console
3Identify whether the 404 is styled or bareBrowser
4Flush rewrite rulesSettings → Permalinks → Save
5Purge the full page cacheCache plugin → Purge All
6Retest every sitemap URLBrowser
7Noindex category and author archivesSEO plugin → Titles & Meta
8Remove those archives from the sitemapSEO plugin → Sitemap Settings
9View-source a blog article and search for your nav linksBrowser
10Check every template has a real meta descriptionBrowser
11Delete backup files from the web rootFile Manager
12Run the live URL inspection testSearch Console
13Resubmit the sitemap indexSearch Console
14Read the Links report and count your referring domainsSearch Console
Do not click “Validate Fix” yet. Validating before your changes are live and crawled puts the report into a failed state and Google becomes slower to re-check. Wait until pages start moving on their own.

Quick reference

Reading a sitemap 404

ObservationMost likely causeFirst action
All sitemap URLs 404Rewrite rules stale, or module disabledFlush permalinks
Some 200, some 404Partially stale rewrite rulesFlush permalinks
Loads for you, 404 for GoogleCache or bot-blockingPurge cache; live URL test
Styled 404 page returnedRouting fault, not a missing fileFlush permalinks
Bare server 404File or rule genuinely absentCheck plugin and .htaccess
Cross-host URLs inside the sitemapwww / non-www mismatchNormalise to the canonical host

Reading an indexing report

StatusMeaningResponse
Discovered — not indexedKnown, never crawledInternal links, sitemap, authority
Crawled — not indexedFetched, judged not worth indexingContent quality, duplication
Blocked by robots.txtExplicitly disallowedEdit robots.txt
Page with redirectRedirecting elsewhereUsually correct — leave alone
Duplicate, different canonicalGoogle picked another URLCheck canonical tags
Last crawled: N/ANever fetched at allCrawl priority, not content quality

Commands and paths

# Flush WordPress rewrite rules

Settings → Permalinks → Save Changes

wp rewrite flush –hard

wp rewrite list | grep sitemap

# Purge LiteSpeed

LiteSpeed Cache → Toolbox → Purge All

# Inspect what the server actually sent

Ctrl+U            view source (not Inspect)

Ctrl+F noscript   confirm crawlable fallback links

Ctrl+F noindex    confirm robots meta

# Live crawlability test

Search Console → URL Inspection → TEST LIVE URL

# Count referring domains

Search Console → Links → Top linking sites

Frequently asked

  • Does a sitemap error stop my site from ranking?

    Not directly. Pages already indexed keep ranking. What it stops is efficient discovery of new and updated pages, and on a site without much authority, that is a real cost. New content can sit undiscovered for weeks.

  • How long until Google re-reads my sitemap after I fix it?

    Resubmitting in Search Console usually prompts a read within a few days. If the previous read failed, resubmit rather than waiting. Google backs off after a failure and will not necessarily retry soon on its own.

  • Should I noindex category archives on every site?

    No. If a category holds a genuine body of posts and reads as a useful hub, index it. The test is whether the archive offers something the individual posts do not. One post per category fails that test; twenty posts with a written introduction passes it.

  • Is a noscript navigation fallback still necessary if Google renders JavaScript?

    Google does render JavaScript, so a JS-rendered nav is not invisible. But rendering happens on a deferred second pass, and links present in the raw HTML are discovered sooner and more reliably. On a site with limited crawl budget, the difference is material, and a page with no links at all in its server HTML has nothing for the first pass to follow.

  • How many referring domains do I need?

    There is no fixed number, and anyone quoting one is guessing. What matters is relative: look at who currently ranks for your target term and compare. For a competitive local commercial keyword, a handful of referring domains is rarely enough, however clean the markup.

I run Lami Godlove Digital, a digital marketing agency in Limbe, Cameroon. We build websites, rank them on Google, and write the copy that sells as one system rather than three separate suppliers. If your site is technically clean and still going nowhere, that is usually a diagnosable problem, and we are happy to tell you plainly where it is leaking.

keep reading

More on this.

next step

Rather have us do it?

Every article here is something we do for clients every week. If you would rather hand it over than follow the steps, that is what we are for.

Book Me Now View all services

Scroll to Top