There have on occasion been miners (or mining pools) that have failed to create the maximum allowed block reward in their blocks. Therefore, the actual total will end up being less than the 20,999,999.9769 Bitcoins that were theoretically possible when Bitcoin first started.
There are other considerations too. For example, the very first block reward of 50 BTC can never be spent, as the coinbase transaction from the genesis block was never added to the transaction database. There have been two instances of a miner overwriting the block reward from a previous block and therefore effectively permanently burning 100 BTC, before this bug was fixed. There have been a not insignificant number of coins sent to OP_RETURN outputs or other outputs which are
provably unspendable. And as you say,
a number of examples of miners failing to claim the full block reward and/or the full amount of fees, resulting in them also being irretrievably lost.
It would be very interesting for someone to go through the entire UTXO set and total up the number of provably lost coins which could be subtracted from the maximum possible supply.
I actually did go through all the transactions with an own blockchain parser i have created (this is why i ended up asking this question) and I have found around 3500 BTC (roughly) to be sent to a non spendable output. That was just a high level rough observation, might me much more.
it was simply the difference between balances of all public keys (addresses) as of the time of running the query minus all block rewards ever issued. not sure if that is accurate enough.