One-time codes can be perfectly correct on your phone and rejected by the server in the same second. Both sides compute the same function from a shared secret and the current time step, so a disagreement about the time produces a disagreement about the code. That makes clock drift a security-relevant fault rather than an annoyance.

Two clocks matter here, and fixing the visible one is the part people do first. The one that usually needs attention is the other one.

The Code Is a Function of Time, Not a Password

TOTP takes the shared secret and a counter derived from the current time, runs both through a keyed hash, and truncates the result to a short decimal string, as specified in RFC 6238. The counter advances every time step, conventionally thirty seconds, so the same secret produces a new value when the step changes. The verifier recomputes the expected value for the current step and compares, which requires the same secret and the same idea of now. A password stays reusable until it is changed, while this value expires on a boundary the client cannot see.

That is why one code works and the next fails moments later. It also explains why copying a code out of a chat message is such an unreliable habit.

Two Clocks Have to Agree, Not One

Enrolment material is the first shared thing, and time is the second. If the secret is right while the clocks differ by more than the tolerated window, every generated value lands in the wrong step and is rejected. If the clocks agree while the secret is wrong, every value is rejected as well, and both failures look identical from the login screen. Separating them means checking the account entry and the time independently, in that order.

The verifier's clock deserves the same scrutiny as the device's. A server whose time source is broken rejects correct codes from every user at once, and the reports will describe a sudden outage rather than a drift. That pattern is worth recognising, because its fix belongs on the server and not on a hundred phones.

What Widening the Window Costs

Implementations may accept a code from an adjacent step to absorb small differences, and that tolerance is a design decision rather than a free adjustment. Every extra step multiplies the number of values valid at any moment, which is exactly what a guessing attacker prefers. The replay rule matters for the same reason, since a code accepted twice is a code that leaked usefully. An administrator widening the window to silence complaints trades a real property for a cosmetic improvement.

Correcting the clock is the repair, while widening the window is a sedative. The first removes the cause and the second hides it.

Check Both Clocks Before You Retry

Read the time on the device and on the server, and compare the offsets rather than the displayed local times. The commands below show synchronisation state and the raw UTC instant on a Linux host or server. Run them on both ends before changing any authentication setting.

timedatectl
date -u +'%Y-%m-%dT%H:%M:%SZ'
chronyc tracking
timedatectl timesync-status

An offset measured in seconds is harmless, one measured in minutes explains a rejection, and a system reporting no synchronisation source is a candidate for both. Compare the two UTC timestamps directly, since local time includes a timezone the algorithm never sees. If the offsets are small and the codes still fail, stop adjusting clocks and inspect the enrolment entry instead. Repeated attempts against a locked account make the original fault harder to observe.

Record the rejection time, the offset and the error text, and leave the shared secret out of it. Support can work with the first three and should never see the fourth.

ସମ୍ପର୍କିତ ପ୍ରବନ୍ଧ