It also seems rare to find bugs in production that cannot be replicated on developer machines so I don't think getting an exact match on the preprod environment is a huge obstacle.
If you have a small change, it is easily testable, and the chance of it breaking something is small. The goal isn't to discover bugs on production, it's to make it extremely easy to fix bugs on production. Continuous delivery batches up many small changes and thus makes it more difficult to figure out what exactly the issue is when you discover one. I have yet to see a process that is able to release bug free code, so knowing that bugs do get to production as a matter of life, it is highly optimal to make your process make those bugs easier to fix. Ultimately you end up with fewer bugs, when you do have bugs they have smaller impact, and when you need to fix them they are easy to track down and fast to change.
Getting an exact match on preprod is extremely difficult when you have a relatively complex data environment (sharding etc.), a relatively complex build environment (assets built differently in production than dev) etc.
Is continuous deployment just something for teams that don't know how to make a copy of their production server?