beemdevelopment/Aegis · error
Host not present in URI
Error message
Host not present in URI: %s
What it means
Generic validation guard in parseUri(Uri): when the URI's type segment (host) does not map to a known OTP type such as totp/hotp/steam/motp, the code falls through to a default branch that reports the unrecognized host value. It fires on otpauth URIs with a wrong or missing type, e.g. otpauth://foo/...
Solutions
- Include the OTP type as the URI host: otpauth://totp/... or otpauth://hotp/...
- Re-generate the QR/URI with a standard generator library
- Validate the URI contains a known host before importing
Example fix
// before String uri = "otpauth://?secret=JBSWY3DPEHPK3PXP"; // after String uri = "otpauth://totp/Example:alice?secret=JBSWY3DPEHPK3PXP";
Defensive patterns
Strategy: validation
Validate before calling
if (uri.getHost() == null) throw new IllegalArgumentException("otpauth URI missing type host"); Type guard
boolean hasOtpType(Uri u) { return u.getHost() != null; } Try / catch
try { return GoogleAuthInfo.parseUri(uri); } catch (GoogleAuthInfoException e) { showMalformedUriError(uri); return null; } Prevention
- Always format otpauth URIs as otpauth://<type>/<label>?params
- Use a maintained otpauth URI generator library
- Preview/validate URIs in unit tests before shipping QR generation
When it happens
Trigger: parseUri(Uri) with a URI like otpauth://?secret=... (no host component), e.g. otpauth://totp written without the host or a malformed scheme-specific part.
Common situations: Hand-written otpauth URIs, QR generators emitting otpauth:///label forms, or strings where the type was stripped during transfer.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
AI-assisted analysis of beemdevelopment/Aegis@d6f4e5925a (2026-09-08).
Data as JSON: /api/errors/6656e666ab45141d.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java:71
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()));
}
switch (type) {
case "totp":
TotpInfo totpInfo = new TotpInfo(secret);
String period = uri.getQueryParameter("period");
if (period != null) {
totpInfo.setPeriod(Integer.parseInt(period));
}
info = totpInfo;
break;
case "steam":
SteamInfo steamInfo = new SteamInfo(secret);
period = uri.getQueryParameter("period");
if (period != null) {
steamInfo.setPeriod(Integer.parseInt(period));
}
info = steamInfo;View on GitHub (pinned to d6f4e5925a)