happytails.ai

TOTP diagnostic tool

Check why an authenticator code is rejected by listing TOTP codes around a time you choose. Paste a Base32 secret or otpauth URI and see which time step, if any, matches the code your app shows.

Input is one Base32 secret or otpauth URI of up to 4096 characters decoding to 1 to 128 bytes. The time must fall between 1970-01-01T00:00:00Z and 9999-12-31T23:59:59Z. The observed code has 6 to 8 digits and at most 32 characters including spaces. Up to 20 steps are checked on each side, with 6 to 8 digits and steps of 1 to 3600 seconds. Everything runs locally in your browser. Download a JSON report and a CSV of codes per time step. Paste the Base32 secret or the otpauth:// link from your two-factor setup. Up to 4,096 characters. Review the settings before running.

Your result

Report a problem or share an idea.

How to use TOTP diagnostic tool
  1. Paste the Base32 secret or the full otpauth URI from your setup screen.
  2. Enter the evaluation time in UTC, or Unix seconds, and the code your app shows.
  3. Check the algorithm, digits and time step, or let the otpauth URI set them.
  4. Run the tool and read which offset matches to see the clock drift.

Useful next steps

What it computes

Codes follow RFC 6238 (TOTP, May 2011) using the HOTP truncation from RFC 4226 (December 2005). The time step counter is the Unix time divided by the step length, rounded down. The tool lists codes for each step on both sides of the time you enter and marks the step that matches your observed code.

Reading the result

A match at offset 0 means the clocks agree. A match at another offset means one clock is that many steps fast or slow. No match usually means a different secret, algorithm or digit count.

Assumptions and limits

The time is never taken from your device clock; you enter it so results can be reproduced. The secret stays in the page and is not written to the report. Secrets shorter than 16 bytes are flagged as weak. If the last character of the secret leaves spare bits that are not zero, they are dropped the way authenticator apps do and the report sets secretTrailingBitsIgnored to true. The observed code may be grouped with spaces, as apps show it.