{"record":{"id":"2e11599975642f82","repo":"HMCL-dev/HMCL","slug":"file-name-is-malformed","errorCode":null,"errorMessage":"File ${name} is malformed","messagePattern":"File (.+?) is malformed","errorType":"exception","errorClass":"ArtifactMalformedException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/mojang/MojangJavaDownloadTask.java","lineNumber":126,"sourceCode":"\n                    String rawSha1;\n                    if (raw != null && raw.getSha1() != null) {\n                        rawSha1 = raw.getSha1();\n                    } else {\n                        rawSha1 = null;\n                    }\n\n                    Path tempFile = tempDir.resolve(entry.getKey() + \".lzma\");\n                    var task = new FileDownloadTask(downloadProvider.injectURLWithCandidates(download.getUrl()), tempFile,\n                            new FileDownloadTask.IntegrityCheck(\"SHA-1\", download.getSha1()));\n                    task.setName(entry.getKey());\n                    dependencies.add(task.thenRunAsync(() -> {\n                        Path decompressed = tempDir.resolve(entry.getKey() + \".tmp\");\n                        var digest = MessageDigest.getInstance(\"SHA-1\");\n                        try (var input = new DigestInputStream(new LZMAInputStream(Files.newInputStream(tempFile)), digest)) {\n                            Files.copy(input, decompressed, StandardCopyOption.REPLACE_EXISTING);\n                        } catch (IOException e) {\n                            throw new ArtifactMalformedException(\"File \" + entry.getKey() + \" is malformed\", e);\n                        }\n\n                        String actualSha1 = HexFormat.of().formatHex(digest.digest());\n\n                        if (rawSha1 != null && !actualSha1.equalsIgnoreCase(rawSha1)) {\n                            throw new ArtifactMalformedException(\"File \" + entry.getKey() + \" has incorrect SHA-1 hash: expected \" + rawSha1 + \", got \" + actualSha1);\n                        }\n\n                        try {\n                            Files.deleteIfExists(tempFile);\n                        } catch (IOException e) {\n                            LOG.warning(\"Failed to delete temporary file: \" + tempFile, e);\n                        }\n\n                        Files.move(decompressed, dest, StandardCopyOption.REPLACE_EXISTING);\n                        if (file.isExecutable()) {\n                            FileUtils.setExecutable(dest);\n                        }","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/mojang/MojangJavaDownloadTask.java#L108-L144","documentation":"During execution, MojangJavaDownloadTask decompresses each LZMA-compressed runtime file from the downloaded archive while computing its SHA-1. If reading or writing the decompressed data throws IOException, the file is considered corrupt/incomplete and ArtifactMalformedException wraps the cause, aborting the Java runtime installation.","triggerScenarios":"LZMAInputStream failing mid-decompression (truncated/corrupt download) or Files.copy failing on write, inside execute()'s per-entry dependency task for a runtime file entry.","commonSituations":"Interrupted or flaky network producing a truncated runtime archive; disk full or permission issues on the temp directory; antivirus locking the temporary file during decompression.","solutions":["Delete the partially downloaded Java runtime directory/cache and re-download.","Check free disk space on the drive holding the temp directory.","Exclude HMCL/temp dirs from antivirus or close programs locking the files, then retry.","Retry on a stable network or switch to another download provider/mirror."],"exampleFix":"// Not caller-fixable; recovery:\n// 1) Settings -> Java -> delete the broken managed Java runtime\n// 2) re-trigger the Java download to get a fresh archive","handlingStrategy":"retry","validationCode":"// Before install, verify archive size and free disk space\nif (Files.size(archive) < expectedMinBytes) throw new IOException(\"Truncated download\");\nif (Files.getFileStore(tempDir).getUsableSpace() < requiredBytes) throw new IOException(\"Low disk space\");","typeGuard":"null","tryCatchPattern":"try { task.run(); } catch (ArtifactMalformedException e) {\n    LOG.warning(\"Runtime file corrupt: \" + e.getMessage(), e);\n    Files.deleteIfExists(runtimeDir); // then re-download once\n}","preventionTips":["Re-download after any interrupted transfer instead of resuming partially.","Keep several GB free on the drive holding HMCL's data directory.","Exclude the game/HMCL directories from antivirus scanning.","Use a stable connection or a closer mirror for large runtime downloads."],"tags":["download","decompression","corrupt-file","io"],"backgroundTag":"file-read-failed","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"}