I've been using keycloak 1.9.1 (dockerized if that makes any difference) and haven't been able to figure out how to get TOTP working. I've tried it with android's FreeOTP, as well as Google's authenticator, still with no luck. I can specify keycloak to use TOTP, login and get the QR code displayed, scan it with my phone and get the OTP, but when I enter it it's always rejected. Does anyone have this working currently?
Whenever I got the "Invalid authenticator code" error, I had it fixed by syncing my computer's clock with my smartphone's clock. If your computer gets the time from a server, and the server is off even by seconds, you won't be able to register nor use TOTP. In this scenario, you may correct the time, but you will lose access again when your computer syncs to the server.
If you have a skew between your server and your phone's time, TOTP registration and login won't work, as your phone's code and the server's code won't match. Also, you might want to check if both of them are in the same timezone.
Additionally, you can increase the "Look Ahead Window" in the Authentication -> OTP Policy screen (sorry, I'm unable to embed images yet).
This option gives Keycloak some tolerance about clock skewing, by letting it consider some oncoming future codes. However, it seems that this option doesn't allow Keycloak to look backwards, so a slow smartphone clock may not work, even when the "Look Ahead Window" is set to the max.