beemdevelopment/Aegis · error

Parameter 'secret' is not present

Error message

Parameter 'secret' is not present

What it means

The otpauth:// URI parsed successfully and had a valid scheme, but the required 'secret' query parameter is missing. Every OTP URI must carry the shared secret; without it no authenticator can be constructed.

Solutions

  1. Regenerate the otpauth URI including the secret query parameter (Base32 for totp/hotp, hex for motp)
  2. Check the importing service's URI construction/documentation
  3. Catch GoogleAuthInfoException and report the URI as incomplete to the user

Example fix

// before
String uri = "otpauth://totp/Example:alice?issuer=Example";
// after
String uri = "otpauth://totp/Example:alice?issuer=Example&secret=JBSWY3DPEHPK3PXP";
Defensive patterns

Strategy: validation

Validate before calling

if (uri.getQueryParameter("secret") == null) throw new IllegalArgumentException("URI missing secret parameter");

Try / catch

try { return GoogleAuthInfo.parseUri(uri); } catch (GoogleAuthInfoException e) { promptForMissingSecret(); return null; }

Prevention

When it happens

Trigger: parseUri(Uri) encountering a URI like otpauth://totp/label?issuer=X with no secret= parameter.

Common situations: Hand-crafted otpauth URIs missing the secret, provider exports that put the secret elsewhere, or QR generators that omit the parameter.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java:53

    public static GoogleAuthInfo parseUri(String s) throws GoogleAuthInfoException {
        Uri uri = Uri.parse(s);
        if (uri == null) {
            throw new GoogleAuthInfoException(uri, String.format("Bad URI format: %s", s));
        }
        return GoogleAuthInfo.parseUri(uri);
    }

    public static GoogleAuthInfo parseUri(Uri uri) throws GoogleAuthInfoException {
        String scheme = uri.getScheme();
        if (scheme == null || !(scheme.equals(SCHEME) || scheme.equals(MotpInfo.SCHEME))) {
            throw new GoogleAuthInfoException(uri, String.format("Unsupported protocol: %s", scheme));
        }

        // 'secret' is a required parameter
        String encodedSecret = uri.getQueryParameter("secret");
        if (encodedSecret == null) {
            throw new GoogleAuthInfoException(uri, "Parameter 'secret' is not present");
        }

        byte[] secret;
        try {
            secret = (scheme.equals(MotpInfo.SCHEME)) ? Hex.decode(encodedSecret) : parseSecret(encodedSecret);
        } catch (EncodingException e) {
            throw new GoogleAuthInfoException(uri, "Bad secret", e);
        }
        if (secret.length == 0) {
            throw new GoogleAuthInfoException(uri, "Secret is empty");
        }

        OtpInfo info;
        String issuer = "";
        try {
            String type = (scheme.equals(MotpInfo.SCHEME)) ? MotpInfo.ID : uri.getHost();
            if (type == null) {
                throw new GoogleAuthInfoException(uri, String.format("Host not present in URI: %s", uri.toString()));

View on GitHub (pinned to d6f4e5925a)