beemdevelopment/Aegis · error · OtpInfoException

Yandex secret checksum invalid

Error message

Yandex secret checksum invalid

What it means

For full-length Yandex secrets, validateSecret recomputes the CRC-like checksum (accumulator over bits) and compares it to the embedded original checksum. A mismatch means the secret bytes are corrupted or altered, so OtpInfoException('Yandex secret checksum invalid') is thrown.

Solutions

  1. Re-obtain the secret from Yandex (fresh QR code or re-export) — the stored bytes are corrupt
  2. Re-check the decoding path: ensure the same base32 alphabet/encoding was used as when the secret was created
  3. Verify no characters were lost/altered during copy-paste (especially trailing characters)
  4. If only the checksum is bad but codes otherwise work, treat the entry as untrusted and replace it rather than bypassing validation

Example fix

// before
try {
    YandexInfo.validateSecret(secret);
} catch (OtpInfoException e) {
    secret = corruptSecret; // never reuse a checksum-failed secret
}
// after
try {
    YandexInfo.validateSecret(secret);
} catch (OtpInfoException e) {
    Log.e(TAG, "Yandex secret failed checksum; re-scan the QR code", e);
    throw new InvalidEntryException("Re-import the Yandex entry from a fresh QR code");
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    YandexInfo.validateSecret(secret);
} catch (OtpInfoException e) {
    throw new InvalidEntryException("Yandex secret failed checksum; re-import from a fresh QR code", e);
}

Prevention

When it happens

Trigger: Calling YandexInfo.validateSecret(byte[]) (via parseSecret) with a SECRET_FULL_LENGTH secret whose embedded checksum bits do not match the recomputed accumulator — e.g. one or more flipped bits in transmission/storage.

Common situations: Copy/paste corruption when manually transcribing Yandex secrets, encoding/decoding round-trip errors (case-sensitive base32 variants), secrets edited or truncated by intermediate tools.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of beemdevelopment/Aegis@d6f4e5925a (2026-09-08). Data as JSON: /api/errors/02b82bea2a7e7bc5. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/com/beemdevelopment/aegis/otp/YandexInfo.java:160

                inputTotalBitsAvailable -= bitsToRead;
                requiredBits -= bitsToRead;
                inputBitsAvailable -= bitsToRead;
                accumBits += bitsToRead;

                if (inputBitsAvailable == 0) {
                    inputIndex += 1;
                    inputBitsAvailable = 8;
                }
            }

            if (accumBits == 13) {
                accum ^= 0b1_1000_1111_0011;
            }
            accumBits = 16 - getNumberOfLeadingZeros(accum);
        }

        if (accum != originalChecksum) {
            throw new OtpInfoException("Yandex secret checksum invalid");
        }
    }

    private static int getNumberOfLeadingZeros(char value) {
        if (value == 0) {
            return 16;
        }

        int n = 0;
        if ((value & 0xFF00) == 0) {
            n += 8;
            value <<= 8;
        }
        if ((value & 0xF000) == 0) {
            n += 4;
            value <<= 4;
        }
        if ((value & 0xC000) == 0) {

View on GitHub (pinned to d6f4e5925a)