Handle TOTP Time Drift Issues
Diagnose and fix TOTP time drift problems that cause authentication failures. Learn about NTP synchronization, server-side drift compensation, and resynchronization strategies.
Detailed Explanation
Solving TOTP Time Drift Problems
Time drift is the most common cause of TOTP authentication failures. Because TOTP depends on synchronized clocks, even a small difference between the server and the user's device can cause valid codes to be rejected.
What Causes Time Drift?
- Device clock inaccuracy: phones and computers can drift by seconds or minutes over time without NTP correction
- Manual time changes: users manually setting their clock or timezone
- VM clock skew: virtual machines, especially after suspend/resume, can have significant clock drift
- NTP failures: if the server or device cannot reach an NTP server, the clock drifts uncorrected
Measuring Drift
During verification, track the offset at which codes match:
for offset in range(-window, window + 1):
if verify_at_offset(secret, token, offset):
log_drift(user_id, offset)
return True
If a user consistently matches at offset = -1 or +1, their clock is drifting by approximately 30 seconds.
Server-Side Mitigation
1. Widen the Validation Window
Accept codes from adjacent time steps:
Standard: T-1, T, T+1 (90 seconds)
Lenient: T-2, T, T+2 (150 seconds)
Trade-off: wider windows increase the time an intercepted code remains valid.
2. Adaptive Drift Tracking
Store the last known drift offset per user and adjust the validation center:
# If user's last verified offset was +1, check T, T+1, T+2 first
adjusted_center = current_step + user.last_known_drift
for offset in range(-1, 2):
check_step = adjusted_center + offset
RFC 6238 explicitly recommends this approach: "the validator can store the drift with the user and use it in subsequent verifications."
3. Resynchronization Protocol
If a user is consistently failing, implement a resync flow:
- Ask the user for two consecutive codes (from two different time windows)
- Search a wider window (e.g., T-10 to T+10) for the first code
- Verify the second code matches at the next step
- Store the new drift offset
Client-Side Fixes
Advise users experiencing persistent failures to:
- Enable automatic time on their device (Settings → Date & Time → Automatic)
- Sync with NTP: Google Authenticator has a "Time correction for codes" option under Settings
- Check timezone: ensure the timezone is correct (TOTP uses UTC internally, but wrong timezone settings can indicate deeper clock issues)
- Restart the authenticator app: some apps cache the time at launch
Use Case
Support engineers and backend developers troubleshooting 'my 2FA code doesn't work' reports need systematic approaches to diagnose time drift. This guide covers both immediate fixes (widening the window) and long-term solutions (adaptive drift tracking). It is particularly useful for teams seeing a pattern of authentication failures from specific user segments, such as users on older devices or in regions with unreliable NTP connectivity.