{"record":{"id":"b39766085592de64","repo":"HMCL-dev/HMCL","slug":"self-verification-failed","errorCode":null,"errorMessage":"Self verification failed","messagePattern":"Self verification failed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateChecker.java","lineNumber":88,"sourceCode":"    public static boolean isOutdated() {\n        return outdated.get();\n    }\n\n    public static ObservableBooleanValue outdatedProperty() {\n        return outdated;\n    }\n\n    public static boolean isCheckingUpdate() {\n        return checkingUpdate.get();\n    }\n\n    public static ReadOnlyBooleanProperty checkingUpdateProperty() {\n        return checkingUpdate.getReadOnlyProperty();\n    }\n\n    private static RemoteVersion checkUpdate(UpdateChannel channel, boolean preview) throws IOException {\n        if (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) {\n            throw new IOException(\"Self verification failed\");\n        }\n\n        var query = new LinkedHashMap<String, String>();\n        query.put(\"version\", Metadata.VERSION);\n        query.put(\"channel\", preview ? channel.channelName + \"-preview\" : channel.channelName);\n\n        String url = NetworkUtils.withQuery(Metadata.HMCL_UPDATE_URL, query);\n        return RemoteVersion.fetch(channel, preview, url);\n    }\n\n    private static boolean isDevelopmentVersion(String version) {\n        return version.contains(\"@\") || // eg. @develop@\n                version.contains(\"SNAPSHOT\"); // eg. 3.5.SNAPSHOT\n    }\n\n    public static void requestCheckUpdate(UpdateChannel channel, boolean preview) {\n        Platform.runLater(() -> {\n            if (isCheckingUpdate())","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateChecker.java#L70-L106","documentation":"UpdateChecker.checkUpdate first verifies the running HMCL binary's integrity via IntegrityChecker.isSelfVerified() (unless checks are disabled). If the current jar fails self-verification (its hash does not match the embedded expected hash/signature), it throws IOException(\"Self verification failed\") and refuses to query update servers. This prevents a tampered binary from fetching or trusting update metadata.","triggerScenarios":"Requesting an update check while the executing HMCL jar has been modified after release — rebuilt, patched, repackaged, or corrupted in transfer — so isSelfVerified() returns false and the code path at UpdateChecker.java:88 throws.","commonSituations":"Downloading HMCL from unofficial mirrors or via a corrupted transfer; jars modified by third-party repacks/patches; building HMCL locally without updating the embedded integrity hash; disk corruption of the jar file.","solutions":["Re-download HMCL from the official site/GitHub releases and replace the current jar","If self-built, this is expected — local builds fail the embedded hash check by design","Verify the jar hash against the published checksum","Run with the self-integrity-check disabled flag only if you fully trust the binary (not recommended)"],"exampleFix":"// before\nif (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) {\n    throw new IOException(\"Self verification failed\");\n}\n// after\n// user-side: re-download the official jar; do not bypass.\n// diagnostic:\nLOG.warning(\"Self verification failed for \" + IntegrityChecker.currentJarPath());\nthrow new IOException(\"Self verification failed: the HMCL jar was modified; \"\n    + \"please download the official release\");","handlingStrategy":"validation","validationCode":"// before enabling update checks\nif (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) {\n    // refuse to proceed; prompt the user to re-download the official jar\n    Controllers.dialog(\"HMCL binary integrity check failed. Please re-download from the official site.\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    checkForUpdate();\n} catch (IOException e) {\n    if (\"Self verification failed\".equals(e.getMessage())) {\n        Controllers.dialog(\"Your HMCL jar was modified or corrupted; download the official release\", MessageType.ERROR);\n    } else throw e;\n}","preventionTips":["Only download HMCL from the official GitHub releases or official website","Verify the jar's checksum after download","Do not patch/repackage the HMCL jar if you want update checks to work","Expect self-built jars to fail this check by design"],"tags":["security","integrity","update","checksum"],"backgroundTag":"checksum-mismatch","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}