A canonical tag is a hint Google weighs, not an order it obeys, which is why the URL it picks can differ from the one you set. Google treats your tag as one vote in a larger tally, and when other signals point at a different URL as the better representative, it follows those instead. This isn’t the tag failing at random; it is Google judging that the rest of your site disagrees with it.
The signals that can outvote your canonical are worth naming, because they are usually where the conflict lives. Internal links are the most common culprit: if most of your menus and body links point at the duplicate rather than your declared canonical, Google reads that as your real preference. The sitemap counts too, so listing a non-canonical URL there sends a mixed message. Redirects outrank a canonical tag outright, and so, in effect, can a duplicate that has gathered more external links. Google also leans toward the cleaner, shorter URL and the secure one as tie-breakers, and it will ignore a canonical that points at a page which 404s, redirects, is blocked, or carries noindex.
When Search Console flags this as “Duplicate, Google chose a different canonical than user,” read it as a signal mismatch, not a penalty; the page usually still works, Google has just consolidated differently than you asked. The fix is to make your signals agree. Align your internal links, your sitemap, and your redirects with the canonical you actually want, instead of trusting the tag to carry the decision on its own.