The Trailing-Slash Redirect Bug That Quietly Hurts Indexing
When your host redirects one URL form to the other while your canonicals and sitemap point at the redirecting form, every page sends search engines in a circle. Learn how this happens on static sites, how we found it on ours, and how to check yours in a minute.
Short answer: /pricing and /pricing/ are different URLs. If your host serves one and redirects the other, your canonical tags, sitemap, and internal links must all use the form that is served. If they use the redirecting form, every indexable URL you declare is a redirect to a page whose canonical points back at the redirect. Check with one command: request your canonical URL and confirm it returns 200.
Table of Contents
- How the Mismatch Happens
- What We Found
- Why It Matters
- How to Check Your Site
- How to Fix It
- Keeping It Fixed
- Key Takeaways
How the Mismatch Happens
Three independent parts of a site each decide what a URL looks like.
| Part | Decides | Controlled by |
|---|---|---|
| The build | What files are produced | Your framework's output settings |
| The host | Which URL form is served and which redirects | Hosting or CDN configuration |
| The application | Canonical tags, sitemap entries, internal links | Your code |
Nothing forces them to agree.
On a statically generated site, a route such as /pricing is often written to disk as pricing/index.html. Many static hosts treat a folder with an index file as a directory, and by default serve it at the URL with a trailing slash, redirecting the version without one.
Meanwhile, the application code writes canonical tags and sitemap entries in whichever form the developer typed, usually without the slash.
What We Found
Our marketing site is prerendered to static files and served from a CDN. Each route was emitted as a folder containing an index file.
The CDN's default handling for that structure served /pricing/ with a 200 and answered /pricing with a 307 redirect to the slash version.
Our sitemap listed every URL without a trailing slash. Every canonical tag in the codebase used the same form.
So for all of our indexable pages, around 180 of them:
- The sitemap told search engines to fetch
/pricing. - That URL redirected to
/pricing/. - The page at
/pricing/declared its canonical as/pricing. - Which redirects.
Every page pointed at a redirect as its preferred URL.
Nothing in the application code hinted at this. The redirect direction was set by a default in the hosting configuration, a file most of the team never opened. The pages loaded normally in a browser, because browsers follow redirects without comment.
Why It Matters
- Contradictory signals. A canonical tag says "this is the preferred URL". A redirect away from that URL says the opposite. Search engines have to guess.
- Temporary redirects. A 307 is a temporary redirect. It tells crawlers the original URL may come back, which discourages them from consolidating signals onto the destination.
- Wasted crawling. Each page costs two requests. On a new site with limited crawl attention, that matters.
- Split signals. Links to the two forms may be counted separately.
- Messy reports. Search Console shows pages as redirects, alternates, and duplicates with a different canonical chosen.
An honest note on impact. When we found this, most of our pages were unindexed, and we were inclined to blame this bug for all of it. It did not explain all of it. On inspection it accounted for a handful of canonical-related entries in the indexing report. The larger problem was something else entirely (what it turned out to be). The redirect was still a genuine fault and worth fixing, but a real bug is not automatically the whole explanation.
How to Check Your Site
1. Request your canonical URL
Take the exact URL from a page's canonical tag and request it:
curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/pricingIt must return 200. If it returns 301, 302, 307, or 308, your canonical is a redirect.
2. Request the other form
curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/pricing/One form should return 200 and the other should redirect to it.
3. Compare all three sources
| Check | Should be |
|---|---|
| The URL that returns 200 | Form A |
| The canonical tag | Form A |
| Sitemap entries | Form A |
| Internal links | Form A |
| The other form | A permanent redirect to Form A |
4. Look at Search Console
Entries under "Page with redirect", "Alternate page with proper canonical tag", and "Duplicate, Google chose different canonical than user" across many pages suggest a systematic mismatch.
5. Check the host as well
The same applies to www versus non-www and http versus https. One version should serve, and the rest should redirect to it permanently.
How to Fix It
Pick one form and make all three parts agree. Either is acceptable. Consistency is what counts.
- Change the host to serve the form your application already uses. This was our fix: one setting in the hosting configuration to drop trailing slashes, so the non-slash URLs returned 200 and the slash versions redirected.
- Or change the application to emit canonicals, sitemap entries, and links in the form the host serves.
- Use permanent redirects (301 or 308) for the non-preferred form.
- Update internal links so they do not pass through a redirect.
Changing the host was the smaller change for us, since it was a single line and the application was consistent already.
Keeping It Fixed
- Add a check to your release process. Request a few canonical URLs and fail if any returns something other than 200.
- Treat the three parts as one contract. A change to build output, hosting configuration, or canonical formatting must keep them aligned.
- Recheck after a framework or host upgrade. Defaults change.
- Generate canonicals and sitemap entries from one function, so they cannot disagree with each other.
A browser will not show you this
Browsers follow redirects silently. Use a command-line request, or the network panel with redirects visible, to see the real status code.
Key Takeaways
- With and without a trailing slash are two different URLs.
- Build output, host configuration, and application code must agree on one form.
- Your canonical URL must return 200.
- Browsers hide redirects; check status codes directly.
Conclusion
This bug produced no error, no warning, and no visible symptom. It took one command to find. Run it against your own canonical URLs today.
Frequently Asked Questions
Related articles
Stay in the loop
Get the latest insights on product analytics and user behavior delivered to your inbox.



