{"record":{"id":"f7d5b5668a1c59ee","repo":"HMCL-dev/HMCL","slug":"sha-1","errorCode":null,"errorMessage":"SHA-1","messagePattern":"SHA-1","errorType":"exception","errorClass":"ChecksumMismatchException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java","lineNumber":183,"sourceCode":"                if (!Objects.equals(code, entry.getValue())) {\n                    if (!ZlibUtils.IS_ZLIB_COMPATIBLE && FileUtils.getExtension(artifact).equals(\"jar\")) {\n                        // Forge/NeoForge generates JARs dynamically during installation.\n                        // When native compression libraries such as zlib-ng are in use,\n                        // the resulting JAR may be compressed differently, causing its\n                        // SHA-1 hash to differ from the expected value recorded in the\n                        // install profile. In this case, fall back to verifying that the\n                        // file is at least a structurally valid ZIP/JAR archive.\n                        try {\n                            FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER.checkIntegrity(artifact, artifact);\n                            LOG.info(\"Ignoring SHA-1 mismatch for \" + artifact + \" due to non-standard zlib compression output\");\n                            continue;\n                        } catch (Exception ignored) {\n                        }\n                    }\n\n\n                    Files.delete(artifact);\n                    throw new ChecksumMismatchException(\"SHA-1\", entry.getValue(), code);\n                }\n            }\n        }\n    }\n\n    private final DefaultDependencyManager dependencyManager;\n    private final DefaultGameRepository gameRepository;\n    private final GameInstanceManifest manifest;\n    /// Source vanilla client JAR copied before processors are invoked.\n    private final Path minecraftJar;\n    private final Path installer;\n    private final List<Task<?>> dependents = new ArrayList<>(1);\n    private final List<Task<?>> dependencies = new ArrayList<>(1);\n\n    private ForgeNewInstallProfile profile;\n    private List<Processor> processors;\n    private GameInstanceManifest forgeVersion;\n    private final String selfVersion;","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java#L165-L201","documentation":"ChecksumMismatchException thrown after a processor output exists but its SHA-1 does not match the value declared in install_profile.json. HMCL deletes the mismatching artifact to avoid leaving a bad file. This is the post-processor integrity gate for Forge installation; note HMCL already falls back to a ZIP-integrity check when non-standard zlib compression changes jar hashes.","triggerScenarios":"After running a processor, DigestUtils.digestToString(\"SHA-1\", output) differs from entry.getValue() and the zlib-compatibility fallback (ZIP_INTEGRITY_CHECK_HANDLER) also fails or does not apply, so the artifact is deleted and the exception is raised.","commonSituations":"zlib-ng or other non-standard compression altering jar bytes on systems where IS_ZLIB_COMPATIBLE is true; a buggy or tampered processor producing wrong output; profile hashes for a different Forge version than the installed one; disk corruption.","solutions":["Ensure the launcher's zlib handling matches the platform (the mismatch may be benign compression difference on zlib-ng systems)","Delete the version's partially installed files and re-run the Forge installation to regenerate outputs","Verify the installer JAR matches the official Forge download (hash), since profile hashes must match the processors","Update HMCL, which tracks known zlib-compression incompatibilities and applies the ZIP-integrity fallback"],"exampleFix":"// benign mismatch due to zlib-ng: prefer an HMCL build where IS_ZLIB_COMPATIBLE is false,\n// or verify jar integrity manually\ntry {\n    FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER.checkIntegrity(artifact, artifact);\n    // jar is structurally valid; hash mismatch from compression is acceptable\n} catch (Exception e) {\n    Files.delete(artifact); // genuinely bad output\n    throw new ChecksumMismatchException(\"SHA-1\", expected, actual);\n}","handlingStrategy":"try-catch","validationCode":"// Preflight: verify the installer matches official hashes so profile SHA-1 expectations are trustworthy\nString sha1 = DigestUtils.digestToString(\"SHA-1\", new FileInputStream(installer.toFile()));\nif (!officialSha1.equals(sha1)) throw new IOException(\"Installer hash mismatch, re-download\");","typeGuard":null,"tryCatchPattern":"try {\n    installTask.run();\n} catch (ChecksumMismatchException e) {\n    // algorithm='SHA-1': retry once after deleting partial outputs;\n    // if on zlib-ng systems, use an HMCL build with the ZIP-integrity fallback\n}","preventionTips":["Only install from official installer downloads (verify SHA-1)","Keep HMCL updated for zlib-compatibility handling of dynamically generated jars","Clean the version directory and retry when a checksum mismatch occurs after launcher/disk changes"],"tags":["forge","sha1","checksum","processor-output"],"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"}