Our sitemap listed 419 blog posts. Search Console had one of them indexed.
Nothing was blocked. robots.txt was fine, there was no noindex, the pages loaded, the content was real and the sitemap was submitted and being read. Google was finding the URLs and declining to keep them.
The cause was one line of configuration that was, in isolation, entirely reasonable.
The two halves of the problem
Half one, in the framework. Our Astro config set:
trailingSlash: 'never'
That is a defensible choice. It means the site’s canonical form of a URL is /blog/my-post — no trailing slash — and Astro generates canonicals and sitemap entries to match.

Half two, on the host. Cloudflare Pages serves a statically built site as directories. A page built to dist/blog/my-post/index.html is served at /blog/my-post/ with the slash. Ask for it without, and you get a 308 Permanent Redirect to the version with.
Neither half is a bug. Together they meant every URL we published — every canonical tag, every sitemap entry — pointed at an address that immediately redirected somewhere else.
Why a redirect is worse than an error here
A 404 is loud. Someone notices, something alerts, it gets fixed that afternoon.
A 308 is silent and, to a human, invisible. Click one of those URLs in a browser and the page appears instantly. Everything looks correct. Testing by clicking around finds nothing wrong, which is exactly why this survived as long as it did.

To a crawler, it reads differently. A canonical tag is a declaration: this is the real address of this page. When that address answers with a redirect, the page is telling Google that its own preferred URL is not the URL it is served at. Google follows the redirect, finds the content, and now has a self-contradicting signal about which address to keep. The safe response — and the one we got — is to hold the URL as discovered and not commit it to the index.
The sitemap compounded it. Every entry pointed at the redirecting form, so the single strongest hint we could give was 419 instructions to go somewhere else.
Finding it
The symptom that made us look was the ratio. “Discovered – currently not indexed” against a sitemap that size is not a content-quality story; content quality does not produce a clean 419-to-1 split. Something structural was rejecting the URLs as a class.
The check that confirmed it takes one command:
curl -sI -o /dev/null -w '%{http_code}\n' https://example.com/blog/some-post

If a URL from your own sitemap returns 301 or 308 rather than 200, stop and fix that before touching anything else on your SEO list. It does not matter how good the content is if the address you are advertising is not the address that serves it.
The fix, and the part everyone forgets
Aligning the config to the host is the easy half — make the canonical form match what the server actually serves, so canonicals and sitemap entries resolve 200 directly.

The half that takes real work is everything already written.
Across our sites we found and normalised 1,909 internal links that were missing their trailing slash. Every one of them worked. Every one of them cost a redirect hop, and every one of them passed link equity through a 308 instead of directly.
Two things we learned doing that at scale:
Only rewrite links you can prove resolve. The rewriting script built a set of every real route from the pages directory, the content collections and public/, then rewrote a link only if the target was in that set. Blind find-and-replace on a slash is how you turn 1,900 working redirects into some number of confident 404s. The same pass surfaced five internal links pointing at pages that had never existed.
Template literals hide from your search. A plain href="/blog/post" is easy to find. A href={`/blog/${slug}`} is not, and there are roughly 2,500 of those still outstanding on two of our sites. If your grep found a suspiciously round number of links, it found the easy ones.
What to check on your own site this week

- Take three URLs straight from your sitemap and
curl -Ithem. Anything that is not200is a problem, no matter how fine it looks in a browser. - Compare your framework’s trailing-slash setting against what your host actually serves. Cloudflare Pages, Netlify and Vercel do not all behave the same way, and the default is not always the one your config assumes.
- Look at the ratio in Search Console, not the count. A handful of unindexed pages is normal. A large sitemap with almost nothing indexed is structural, and no amount of rewriting content will move it.
- When you fix it, fix the internal links too — and only the ones you can prove point somewhere real.

A last note on urgency, since this is the kind of finding that gets scheduled rather than done: the fix ships in one commit, but recovery is on Google’s timetable, not yours. Every day the wrong form stays live is a day of crawl budget spent confirming that your URLs still contradict themselves.
Awesome Apps builds iOS and Android apps for Australian businesses — and runs the websites that launch them, which is how we found this one.
Talk to a Sydney app developer — free.
30 minutes. We'll tell you what your app needs, how long it takes, and what it costs. Real answers, no sales pitch.
Book Free App Strategy Call →Free · 30 minutes · No obligation