Search Console flags URLs in the “Pages” report with “Duplicate, Google chose different canonical than user” — meaning “you declared a canonical, but I (Google) decided a different URL is the real master, so I ignored you.” Translation:
- The URL you wanted indexed won’t be indexed
- The URL you didn’t pick is taking the indexing + ranking credit instead
- All the “I’m voting for this canonical” signals you accumulated from internal and external links are being transferred to Google’s choice, not yours
This is the inverse of “Alternate page with proper canonical tag” (Google agreed with you). Here, Google is publicly telling you “your proposal is rejected.”
Common causes
In rough frequency order:
1. Your canonical points to a weaker-signal page
Google’s canonical-selection inputs, roughly weighted:
- Internal link count (links from your own site)
- External link count and quality
- Content length and quality
- URL shape (short, no params > long, multi-param)
- HTTPS preferred
- Indexing history (already-indexed URLs win over newly discovered ones)
- Sitemap presence
If you canonical to a cold-start new URL but Google has already indexed the “old URL” for months and it has 50 backlinks, Google sticks with the old one.
How to confirm: In Search Console → URL Inspection, see the Google-selected canonical. Then compare the two URLs on: internal link count (link:"/your-url" site search), backlinks (Search Console → Links report), and time since first indexing.
2. Internal links favor Google’s pick
Most common case:
- You redid the site and old URL
/blog/post-old/still has 200 internal links, while new URL/blog/post-new/has only the sitemap entry. Even with new URL self-canonical, Google picks the old one. - Main nav / homepage / category pages all link to
/page?ref=main, but the canonical says/page— Google sees/page?ref=mainas the actually-linked version and picks it.
How to confirm: grep -r "/blog/post-old/" src/ shows how many places in code reference the old URL. Or use Search Console → Links → Internal links to compare the two URLs’ link counts.
3. Sitemap says A, canonical says B
<!-- sitemap.xml -->
<url><loc>https://yourdomain.com/post/</loc></url>
<!-- but page head -->
<link rel="canonical" href="https://yourdomain.com/post?v=2" />
Google tug-of-wars: sitemap is a strong signal, canonical is a strong signal, and when they fight Google leans toward “what looks like the user is actually using” — usually the sitemap version.
4. Case / slash / www. / http vs https inconsistencies
Google treats these as different URLs and will canonicalize to one standard:
https://yourdomain.com/page ← indexed
https://yourdomain.com/page/ ← your canonical, but Google picked the one above
Usually because most internal links use the unslashed version, the server 301-redirects to the slashed version, and the 301 hop weakens the signal enough for Google to override.
5. Two URLs with very high content similarity
When /services/seo-consulting/ and /blog/seo-consulting-guide/ are 80% the same content, Google decides they’re two variants of one page and picks whichever has the stronger signals — regardless of your canonical declarations.
Shortest path to fix
Core principle: either make your preferred URL carry the strongest signals, or surrender and adopt Google’s pick as the master.
Step 1: Decide which URL is actually the master
Open the two conflicting URLs from the report:
- “User-declared canonical”: A
- “Google-selected canonical”: B
Take 1 minute to ask:
- Is B shorter, cleaner, more memorable? → Surrender. Update A’s canonical to point to B.
- A is genuinely the version you want (newer, more comprehensive), but it’s currently low-signal? → Boost A’s signals in Step 2.
- A and B are truly near-duplicates? → Merge them. 301 one to the other.
Step 2: Move all internal links to the master version
Use ripgrep to find them:
# Find every internal link to the non-master URL
rg -l 'href="/old-url/?"' src/
# Replace
rg -l 'href="/old-url/?"' src/ | xargs sed -i '' 's|/old-url/|/new-url/|g'
At minimum, fix:
- Main nav / homepage / category lists all pointing to the master
- In-article references (“see our earlier piece X”)
- The three template links: related posts, prev/next, breadcrumbs
Re-check Search Console → Links → Internal links: the master’s link count should rise.
Step 3: 301 the loser to the master
Once you’ve confirmed A is the master, B must 301 to A. Changing canonical alone isn’t enough:
// firebase.json
{
"hosting": {
"redirects": [
{
"source": "/old-url",
"destination": "/new-url",
"type": 301
}
]
}
}
Or Vercel:
// next.config.js
module.exports = {
async redirects() {
return [
{ source: "/old-url", destination: "/new-url", permanent: true },
];
},
};
A 301 is roughly 10× stronger than a canonical hint for merging signals. Google almost never ignores it.
Step 4: Sync sitemap / canonical / internal links
// sitemap and canonical share one urlFor()
export function urlFor(slug) {
return `https://yourdomain.com/blog/${slug}/`; // note trailing slash
}
Sitemap generator, canonical renderer, breadcrumb links — all import this function. Zero hand-written URLs.
Step 5: Wait 2-4 weeks
After fixing:
- “Request indexing” on the master URL in Search Console
- After 2 weeks, check whether URL Inspection’s Google-selected canonical has switched
- After 4 weeks, check whether the URL shown in actual search results is the master
If it still hasn’t switched:
- Confirm the 301 is actually live (
curl -Ito see HTTP status) - Check internal link replacement didn’t miss directories (especially CMS rich-text fields)
- Last resort: temporarily add
<meta name="robots" content="noindex,follow">to the loser to force it out of the index, leaving only the master available
Prevention
- “The URL with the most internal links is your canonical” — don’t try to beat Google with weak signals
- When restructuring URLs, migrate internal links AND add 301s — not just canonical changes
- Sitemap / canonical / breadcrumbs all go through one
urlFor()helper; no case or slash drift - Merge near-duplicate content into one URL — don’t raise two pages competing with each other
Related
Tags: #SEO #Google #Search Console #Indexing