{"record":{"id":"78fe65f6daa8413c","repo":"beemdevelopment/Aegis","slug":"unsupported-host","errorCode":null,"errorMessage":"Unsupported host","messagePattern":"Unsupported host","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java","lineNumber":187,"sourceCode":"    }\n\n    public static Export parseExportUri(String s) throws GoogleAuthInfoException {\n        Uri uri = Uri.parse(s);\n        if (uri == null) {\n            throw new GoogleAuthInfoException(uri, \"Bad URI format\");\n        }\n        return GoogleAuthInfo.parseExportUri(uri);\n    }\n\n    public static Export parseExportUri(Uri uri) throws GoogleAuthInfoException {\n        String scheme = uri.getScheme();\n        if (scheme == null || !scheme.equals(SCHEME_EXPORT)) {\n            throw new GoogleAuthInfoException(uri, \"Unsupported protocol\");\n        }\n\n        String host = uri.getHost();\n        if (host == null || !host.equals(\"offline\")) {\n            throw new GoogleAuthInfoException(uri, \"Unsupported host\");\n        }\n\n        String data = uri.getQueryParameter(\"data\");\n        if (data == null) {\n            throw new GoogleAuthInfoException(uri, \"Parameter 'data' is not set\");\n        }\n\n        GoogleAuthProtos.MigrationPayload payload;\n        try {\n            byte[] bytes = Base64.decode(data);\n            payload = GoogleAuthProtos.MigrationPayload.parseFrom(bytes);\n        } catch (EncodingException | InvalidProtocolBufferException e) {\n            throw new GoogleAuthInfoException(uri, e);\n        }\n\n        List<GoogleAuthInfo> infos = new ArrayList<>();\n        for (GoogleAuthProtos.MigrationPayload.OtpParameters params : payload.getOtpParametersList()) {\n            OtpInfo otp;","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java#L169-L205","documentation":"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.","triggerScenarios":"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=...).","commonSituations":"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.","solutions":["Ensure the export URI host is exactly 'offline': otpauth-migration://offline?data=...","Re-export the payload from Google Authenticator and copy the full URI without edits","If parsing arbitrary otpauth URIs, route non-migration ones to GoogleAuthInfo.parseUri instead of parseExportUri"],"exampleFix":"// before\nUri uri = Uri.parse(\"otpauth-migration://export?data=...\");\nGoogleAuthInfo.parseExportUri(uri);\n// after\nUri uri = Uri.parse(\"otpauth-migration://offline?data=...\");\nGoogleAuthInfo.parseExportUri(uri);","handlingStrategy":"validation","validationCode":"if (!\"otpauth-migration\".equals(uri.getScheme()) || !\"offline\".equals(uri.getHost())) {\n    throw new IllegalArgumentException(\"Not a valid Google Authenticator export URI\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    GoogleAuthInfo info = GoogleAuthInfo.parseExportUri(uri);\n} catch (GoogleAuthInfoException e) {\n    Log.w(TAG, \"Invalid export URI: \" + e.getMessage());\n}","preventionTips":["Only pass URIs obtained directly from Google Authenticator exports","Validate scheme and host before calling parseExportUri","Never hand-edit export URIs"],"tags":["otp","uri-validation","google-authenticator"],"backgroundTag":"invalid-url-format","analyzedSha":"d6f4e5925a97e4e91593f1542085eae03432a759","analyzedAt":"2026-09-08T00:46:31.111Z","contentChangedAt":"2026-09-08T00:46:31.111Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}