beemdevelopment/Aegis · error · GoogleAuthInfoException
Empty secret (empty authority)
Error message
Empty secret (empty authority)
What it means
The Bitwarden importer handles Bitwarden's special "steam://" URIs, where the TOTP secret is carried in the URI authority. If a steam URI has no authority component (empty secret), GoogleAuthInfoException is thrown since a Steam TOTP entry cannot exist without a secret.
Solutions
- Open the item in Bitwarden and fill in the correct Steam TOTP secret, then re-export
- Fix the URI in the export so the secret appears in the authority: steam://BASE32SECRET
- Remove or skip entries with empty secrets during import
- Verify the seed is valid Base32 after editing
Example fix
// before
String secretString = uri.getAuthority();
if (secretString == null) {
throw new GoogleAuthInfoException(uri, "Empty secret (empty authority)");
}
// after
String secretString = uri.getAuthority();
if (secretString == null || secretString.isEmpty()) {
throw new GoogleAuthInfoException(uri, "Empty secret (empty authority): steam URIs must be steam://<base32secret>");
} Defensive patterns
Strategy: validation
Validate before calling
Uri uri = Uri.parse(s);
if ("steam".equals(uri.getScheme()) && (uri.getAuthority() == null || uri.getAuthority().isEmpty())) {
throw new IllegalArgumentException("steam:// URI missing base32 secret in authority");
} Type guard
static boolean hasSteamSecret(Uri uri) {
return !"steam".equals(uri.getScheme())
|| (uri.getAuthority() != null && !uri.getAuthority().isEmpty());
} Try / catch
try {
info = GoogleAuthInfo.parseUri(s);
} catch (GoogleAuthInfoException e) {
if (e.getMessage().contains("Empty secret")) {
skipEntry(uri, "missing Steam seed");
}
} Prevention
- Ensure each Bitwarden item has a non-empty TOTP seed before export
- Sanity-check exported otpauth/steam URIs for empty authorities
- Fix truncated seeds at the source app, not in the export file
When it happens
Trigger: Importing a Bitwarden export whose otp:// (steam) URI looks like "steam://" or "steam://?..." with no secret before the query string — i.e. the item's TOTP seed was empty or malformed.
Common situations: Bitwarden vault item with an empty/invalid TOTP custom field; hand-crafted URI missing the secret; copy-paste truncation of the seed before saving in Bitwarden.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid number of iterations for PBKDF
- Unexpectedly high number of iterations
- Bad UUID format
- Password incorrect
- unsupported otp type:
AI-assisted analysis of beemdevelopment/Aegis@d6f4e5925a (2026-09-08).
Data as JSON: /api/errors/8b4552a19f238208.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/com/beemdevelopment/aegis/importers/BitwardenImporter.java:119
return result;
}
private static VaultEntry convertEntry(String obj) throws DatabaseImporterEntryException {
try {
GoogleAuthInfo info = BitwardenImporter.parseUri(obj);
return new VaultEntry(info);
} catch (GoogleAuthInfoException | EncodingException | OtpInfoException | URISyntaxException e) {
throw new DatabaseImporterEntryException(e, obj);
}
}
}
private static GoogleAuthInfo parseUri(String s) throws EncodingException, OtpInfoException, URISyntaxException, GoogleAuthInfoException {
Uri uri = Uri.parse(s);
if (Objects.equals(uri.getScheme(), "steam")) {
String secretString = uri.getAuthority();
if (secretString == null) {
throw new GoogleAuthInfoException(uri, "Empty secret (empty authority)");
}
byte[] secret = Base32.decode(secretString);
return new GoogleAuthInfo(new SteamInfo(secret), "Steam account", "Steam");
}
return GoogleAuthInfo.parseUri(uri);
}
}
View on GitHub (pinned to d6f4e5925a)