beemdevelopment/Aegis · error

Unsupported OTP type

Error message

Unsupported OTP type: %s

What it means

The URI's host (OTP type) parsed and was non-null but is not one of the supported types (totp, hotp, steam, YandexInfo.HOST_ID, motp). The library rejects unknown OTP types via this default-branch throw.

Solutions

  1. Use a supported type in the URI host: totp, hotp, steam, or the supported vendor IDs
  2. Lowercase and trim the host before building the URI
  3. Map the unsupported type to totp if it's a standard TOTP variant, or import the entry manually

Example fix

// before
String uri = "otpauth://TOTP/x?secret=JBSWY3DPEHPK3PXP";
// after
String uri = "otpauth://totp/x?secret=JBSWY3DPEHPK3PXP";
Defensive patterns

Strategy: validation

Validate before calling

Set<String> ok = Set.of("totp","hotp","steam"); if (!ok.contains(uri.getHost())) throw new IllegalArgumentException("unsupported OTP type: " + uri.getHost());

Try / catch

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

Prevention

When it happens

Trigger: parseUri(Uri) with a host like otpauth://xotp/... or a typo such as otpauth://TOTP (case-sensitive switch), or proprietary host IDs from other authenticators.

Common situations: Importing URIs generated by other apps with custom types, typos in hand-built URIs, uppercase or trailing-whitespace hosts.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

                        throw new GoogleAuthInfoException(uri, "Parameter 'counter' is not present");
                    }
                    hotpInfo.setCounter(Long.parseLong(counter));
                    info = hotpInfo;
                    break;
                case YandexInfo.HOST_ID:
                    String pin = uri.getQueryParameter("pin");
                    if (pin != null) {
                        pin = new String(parseSecret(pin), StandardCharsets.UTF_8);
                    }

                    info = new YandexInfo(secret, pin);
                    issuer = info.getType();
                    break;
                case MotpInfo.ID:
                    info = new MotpInfo(secret);
                    break;
                default:
                    throw new GoogleAuthInfoException(uri, String.format("Unsupported OTP type: %s", type));
            }
        } catch (OtpInfoException | NumberFormatException | EncodingException e) {
            throw new GoogleAuthInfoException(uri, e);
        }

        // provider info used to disambiguate accounts
        String path = uri.getPath();
        String label = path != null && path.length() > 0 ? path.substring(1) : "";

        String accountName = "";

        if (label.contains(":")) {
            // a label can only contain one colon
            // it's ok to fail if that's not the case
            String[] strings = label.split(":");
            if (strings.length == 2) {
                issuer = strings[0];
                accountName = strings[1];

View on GitHub (pinned to d6f4e5925a)