beemdevelopment/Aegis · error

Unsupported host

Error message

Unsupported host

What it means

parseExportUri validates otpauth-migration://offline?data=... URIs used by Google Authenticator exports. The URI's host must be exactly 'offline'; any other host (or a missing host) is rejected with this GoogleAuthInfoException. This guard prevents parsing non-migration URIs that happen to share the scheme.

Solutions

  1. Ensure the export URI host is exactly 'offline': otpauth-migration://offline?data=...
  2. Re-export the payload from Google Authenticator and copy the full URI without edits
  3. If parsing arbitrary otpauth URIs, route non-migration ones to GoogleAuthInfo.parseUri instead of parseExportUri

Example fix

// before
Uri uri = Uri.parse("otpauth-migration://export?data=...");
GoogleAuthInfo.parseExportUri(uri);
// after
Uri uri = Uri.parse("otpauth-migration://offline?data=...");
GoogleAuthInfo.parseExportUri(uri);
Defensive patterns

Strategy: validation

Validate before calling

if (!"otpauth-migration".equals(uri.getScheme()) || !"offline".equals(uri.getHost())) {
    throw new IllegalArgumentException("Not a valid Google Authenticator export URI");
}

Try / catch

try {
    GoogleAuthInfo info = GoogleAuthInfo.parseExportUri(uri);
} catch (GoogleAuthInfoException e) {
    Log.w(TAG, "Invalid export URI: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling GoogleAuthInfo.parseExportUri with a URI whose scheme is otpauth-migration but whose host is not 'offline' (or is null, e.g. otpauth-migration://?data=...).

Common situations: Hand-crafted or truncated export URIs pasted from another app, URIs produced by third-party exporters that use a different host, or URIs corrupted during copy/paste or QR scanning.

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/78fe65f6daa8413c. Report an issue: GitHub.

Appendix: source

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

    }

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

    public static Export parseExportUri(Uri uri) throws GoogleAuthInfoException {
        String scheme = uri.getScheme();
        if (scheme == null || !scheme.equals(SCHEME_EXPORT)) {
            throw new GoogleAuthInfoException(uri, "Unsupported protocol");
        }

        String host = uri.getHost();
        if (host == null || !host.equals("offline")) {
            throw new GoogleAuthInfoException(uri, "Unsupported host");
        }

        String data = uri.getQueryParameter("data");
        if (data == null) {
            throw new GoogleAuthInfoException(uri, "Parameter 'data' is not set");
        }

        GoogleAuthProtos.MigrationPayload payload;
        try {
            byte[] bytes = Base64.decode(data);
            payload = GoogleAuthProtos.MigrationPayload.parseFrom(bytes);
        } catch (EncodingException | InvalidProtocolBufferException e) {
            throw new GoogleAuthInfoException(uri, e);
        }

        List<GoogleAuthInfo> infos = new ArrayList<>();
        for (GoogleAuthProtos.MigrationPayload.OtpParameters params : payload.getOtpParametersList()) {
            OtpInfo otp;

View on GitHub (pinned to d6f4e5925a)