{"record":{"id":"d0dcb691544a8f00","repo":"termux/termux-app","slug":"wrong-checksum-for-s-expected-s-actual-s","errorCode":null,"errorMessage":"Wrong checksum for %s: expected: %s, actual: %s","messagePattern":"Wrong checksum for (.+?): expected: (.+?), actual: (.+?)","errorType":"validation","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"app/build.gradle","lineNumber":206,"sourceCode":"    }\n\n    def remoteUrl = \"https://github.com/termux/termux-packages/releases/download/bootstrap-\" + version + \"/bootstrap-\" + arch + \".zip\"\n    logger.quiet(\"Downloading \" + remoteUrl + \" ...\")\n\n    file.parentFile.mkdirs()\n    def out = new BufferedOutputStream(new FileOutputStream(file))\n\n    def connection = new URL(remoteUrl).openConnection()\n    connection.setInstanceFollowRedirects(true)\n    def digestStream = new java.security.DigestInputStream(connection.inputStream, digest)\n    out << digestStream\n    out.close()\n\n    def checksum = new BigInteger(1, digest.digest()).toString(16)\n    while (checksum.length() < 64) { checksum = \"0\" + checksum }\n    if (checksum != expectedChecksum) {\n        file.delete()\n        throw new GradleException(\"Wrong checksum for \" + remoteUrl + \": expected: \" + expectedChecksum + \", actual: \" + checksum)\n    }\n}\n\nclean {\n    doLast {\n        def tree = fileTree(new File(projectDir, 'src/main/cpp'))\n        tree.include 'bootstrap-*.zip'\n        tree.each { it.delete() }\n    }\n}\n\ntask downloadBootstraps() {\n    doLast {\n        def packageVariant = project.ext.packageVariant\n        if (packageVariant == \"apt-android-7\") {\n            def version = \"2026.02.12-r1\" + \"%2B\" + \"apt.android-7\"\n            downloadBootstrap(\"aarch64\", \"ea2aeba8819e517db711f8c32369e89e7c52cee73e07930ff91185e1ab93f4f3\", version)\n            downloadBootstrap(\"arm\", \"a38f4d3b2f735f83be2bf54eff463e86dc32a3e2f9f861c1557c4378d249c018\", version)","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/termux/termux-app/blob/3df69d1da197dd9bd71a3bafd902dffd720576b4/app/build.gradle#L188-L224","documentation":"Thrown by the downloadBootstrap Gradle task when the SHA-256 checksum of the downloaded (or locally present) bootstrap zip does not match the expected checksum passed to the task. The mismatched file is deleted and the build aborts. This protects against corrupted or tampered bootstrap artifacts.","triggerScenarios":"The remote bootstrap URL serves a different zip than expected (newer build, wrong arch, truncated); the expected checksum in build.gradle is stale/wrong; a network proxy/CDN returned an error page; the local cached zip is corrupt.","commonSituations":"Bootstrap was re-released with a new checksum but build.gradle still has the old one; partial download due to network drop; mirror served wrong content; manual local zip that is out of date.","solutions":["Update the expectedChecksum in build.gradle to match the current bootstrap release for the target arch/version.","Delete the cached bootstrap-<arch>.zip under src/main/cpp so it re-downloads fresh.","Verify the remoteUrl points to the correct arch and release.","Recompute the SHA-256 of a known-good zip and set it as expectedChecksum."],"exampleFix":"// before (stale checksum)\ndownloadBootstrap('aarch64', 'oldsha256...', '0.118.0')\n\n// after (recompute and update)\n// shasum -a 256 bootstrap-aarch64.zip  ->  <newhash>\ndownloadBootstrap('aarch64', '<newhash>', '0.118.0')","handlingStrategy":"retry","validationCode":"def knownSha = new BigInteger(1, MessageDigest.getInstance(\"SHA-256\").digest(Files.readAllBytes(knownGoodZip.toPath()))).toString(16)\nwhile (knownSha.length() < 64) knownSha = \"0\" + knownSha\nassert knownSha == expectedChecksum : \"expectedChecksum is stale\"","typeGuard":null,"tryCatchPattern":"// Re-download once on checksum mismatch, then fail\nint attempts = 0\nwhile (true) {\n    try {\n        downloadBootstrap(arch, expectedChecksum, version)\n        break\n    } catch (GradleException e) {\n        if (++attempts > 1 || !(e.message?.contains(\"Wrong checksum\"))) throw e\n        new File(projectDir, \"src/main/cpp/bootstrap-${arch}.zip\").delete()\n    }\n}","preventionTips":["Keep expectedChecksum in build.gradle in sync with the released bootstrap artifact.","Delete cached bootstrap-*.zip after a failed/aborted download to force a fresh fetch.","Verify the remoteUrl serves the correct arch and release version."],"tags":["gradle","build","bootstrap","checksum","integrity-check"],"backgroundTag":null,"analyzedSha":"3df69d1da197dd9bd71a3bafd902dffd720576b4","analyzedAt":"2026-08-13T22:46:28.294Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}