Canonical tag conflicts caused by WordPress + plugins
Canonical symptoms in WordPress plugins: “Duplicate without user-selected canonical” and wrong canonical targets
I see the same pattern in Google Search Console: “Duplicate without user-selected canonical” spikes, even though each page has a canonical tag.
On WooCommerce sites, a product can load at both WooCommerce sites, a product can load at both /main-category/product-name/ and /main-category/sub-category/product-name/, so Google finds two URLs with the same page.
Often, the canonical tag points to only one version every time, so the other URL looks like an orphaned duplicate. A second symptom shows up after changes like a domain move or a parent slug rename: the page URL updates, but the canonical keeps pointing to the old domain or the old path.
Once you can name these patterns, you can trace where the conflict starts.
Where the conflict comes from: WordPress URL variants vs plugin-selected canonicals
WordPress can serve the same content through more than one URL because routing rules and plugins create alternate paths that still resolve to the same post or product.
WooCommerce adds to this by letting products appear under different category paths, even when you think you have one “real” product URL. Then an SEO plugin has to pick a preferred version for the canonical tag, and its choice may not match what you want.
For example, Yoast may choose the category plus subcategory path because it treats that as the most complete path. After you change URLs, that preferred choice can stay wrong because the plugin may keep older stored data instead of rebuilding it.
To fix the issue, you need to understand how Yoast can output a “wrong” canonical even when its settings look fine.
Failure mechanisms in Yoast: cached/redirecting canonicals and stale indexables
One failure mode comes from Yoast plus caching. Right after you publish, Yoast can output a canonical like https://domain.com/?p=12578, which is the short WordPress link.
That short link often returns a 301 redirect to the real permalink, and the canonical becomes a signal that points through a redirect instead of landing on a clean 200 page.
Google documents redirecting canonicals as a source of canonicalization problems, because the signal stops being clear. Another failure mode is stale “indexables,” which are Yoast’s stored SEO records.
If a URL changes due to a parent page rename, migration, or permalink rewrite, Yoast may keep the old canonical until you force a rebuild. Once you know these mechanics, you can predict what search engines and other tools will do with the mixed signals.
SEO and tooling implications: how search engines and dependent systems react
When Google sees two URLs for the same content and your canonicals do not settle the choice, Search Console reports “Duplicate without user-selected canonical.”
If the canonical points to a non-200 URL, like a redirecting ?p= link or an old domain that now redirects, Google may ignore your canonical and pick its own. That can split ranking signals and slow cleanup after you make changes.
Some third-party tools also trust the canonical as the source of truth, so a bad canonical can cause missing titles, images, or attribution, and it can break workflows that depend on the canonical URL. The fix is not “set more canonicals,” but to choose one strategy and enforce it.
Fix selection: choose one canonical strategy and enforce it (redirects, Yoast settings, or code)
If you want only the category plus subcategory product URL, I would treat the shorter category URL as an alias and force it to the preferred URL.
Add a server-side 301 redirect from /main-category/product-name/ to /main-category/sub-category/product-name/, then confirm Yoast outputs the preferred canonical on the destination URL. This pairs the user path and the canonical signal, which removes ambiguity for crawlers.
If canonicals point to an old path or old domain after a structural change, you should refresh Yoast’s stored data instead of hand-editing every page.
Run the WP-CLI command wp yoast index to rebuild indexables, or use the Yoast Test Helper plugin and click “Reset Indexables tables & migrations,” then let Yoast regenerate canonicals.
After that, remove any manual canonical overrides you added during troubleshooting so you do not lock in outdated targets.
If you catch Yoast outputting redirecting ?p= canonicals when you use a cache plugin, you can override the canonical at the source.
Use the wpseo_canonical filter to return get_the_permalink() for single posts, which forces a direct permalink canonical instead of the short link. Then review your caching setup, because the cache may serve the early canonical output longer than you expect.
Only use manual per-page canonicals as a last resort, because they do not scale and they often hide the root cause.
Once you enforce one preferred URL with redirects and a stable canonical source, Search Console signals and dependent tools usually settle after recrawls.