{"record":{"id":"3a8773a7f75adb6f","repo":"phacility/phabricator","slug":"log-data-hashes-differ-something-is-tragically-wr","errorCode":null,"errorMessage":"Log data hashes differ! Something is tragically wrong!","messagePattern":"Log data hashes differ! Something is tragically wrong!","errorType":"console","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"src/applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php","lineNumber":145,"sourceCode":"\n    echo tsprintf(\n      \"    %s\\n\",\n      pht(\n        '%s: %s -> %s',\n        pht('Stored Chunks'),\n        new PhutilNumber($old_stats['chunks']),\n        new PhutilNumber($new_stats['chunks'])));\n\n    echo tsprintf(\n      \"    %s\\n\",\n      pht(\n        '%s: %s -> %s',\n        pht('Data Hash'),\n        $old_stats['hash'],\n        $new_stats['hash']));\n\n    if ($old_stats['hash'] !== $new_stats['hash']) {\n      throw new Exception(\n        pht('Log data hashes differ! Something is tragically wrong!'));\n    }\n  }\n\n}\n","sourceCodeStart":127,"sourceCodeEnd":151,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php#L127-L151","documentation":"Data-integrity check inside archive-logs: after re-writing a log's chunks in the new mode, the workflow recomputes a hash of the reconstructed log data and compares it with the hash before archival. A mismatch means the byte content changed during the rewrite — the archival did not round-trip — and the command aborts loudly rather than let silent corruption spread. Tragic, and meant to be.","triggerScenarios":"The log is still being written to (a running build keeps appending chunks) while the archival rewrites it, so before/after hashes cover different data; corrupted or partially missing chunks making reconstruction order-dependent; a storage backend (database blob vs file) returning truncated data under load; concurrent archive-logs runs on the same log.","commonSituations":"Running archive-logs while the daemon is still executing builds; two overlapping archival runs; disk-full or DB issues truncating chunk writes; an interrupted earlier archival leaving half-plain half-compressed chunks.","solutions":["Re-run the archival when no builds are running (pause the daemon / let builds finish) so logs are quiescent.","Run with --verbose/--details and inspect the reported old/new chunk counts and hashes to see whether the log grew (data appended) or truly differs.","Check the harbormaster_buildlogchunk table (or file storage) for the affected log ID for truncated or overlapping chunks; repair from the original storage if available.","Ensure only one archive-logs process runs at a time (locks/cron overlap)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: only archive logs whose builds are not running\n$log = id(new HarbormasterBuildLogQuery())\n  ->setViewer(PhabricatorUser::getOmnipotentUser())\n  ->withIDs(array($id))\n  ->needBuilds(true)\n  ->executeOne();\nif ($log->getBuild()->isComplete()) { /* safe to archive */ }","typeGuard":null,"tryCatchPattern":"try {\n  archiveLog($log, $mode);\n} catch (Exception $e) {\n  if (preg_match('/hashes differ/', $e->getMessage())) {\n    // log was likely still being written: wait for the build to finish and retry once\n    waitForBuildCompletion($log);\n    archiveLog($log, $mode);\n  } else {\n    throw $e;\n  }\n}","preventionTips":["Pause the daemon (or wait for all builds to finish) before running archive-logs; live logs can change under the rewrite.","Run exactly one archival process at a time; serialize with a lock in cron wrappers.","Investigate every occurrence — a genuine mismatch means corrupted chunks, not a flake; inspect the chunk table for that log ID."],"tags":["harbormaster","log-archival","data-integrity","checksum","cli"],"backgroundTag":"data-integrity-checksum-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}