phacility/phabricator · critical · PhutilArgumentUsageException

File data integrity check failed. Use "--salvage" to bypass…

Error message

File data integrity check failed. Use "--salvage" to bypass integrity checks. This flag is dangerous, use it at your own risk. Underlying error: %s

What it means

While streaming file data, getFileDataIterator() raised PhabricatorFileIntegrityException: the stored blob does not match the integrity hash recorded when the file was written. The cat workflow catches it and rethrows as a usage exception that advertises --salvage, which nulls the integrity hash and dumps the remaining bytes without verification. Data that fails this check should be treated as corrupted.

Solutions

  1. If you must recover the bytes now, re-run with --salvage: `./bin/files cat --salvage F123` — output is unverified and may be damaged
  2. Restore the file or its blob from backups and re-check
  3. Investigate the storage engine for the corruption source (disk SMART, S3 consistency, DB replication) before trusting other files
  4. If the original source still exists, re-upload the file

Example fix

# before
./bin/files cat F123   # throws: integrity check failed

# after (dangerous, bypasses verification)
./bin/files cat --salvage F123
Defensive patterns

Strategy: try-catch

Try / catch

try {
  $iterator = $file->getFileDataIterator($begin, $end);
  foreach ($iterator as $chunk) {
    // consume verified data
  }
} catch (PhabricatorFileIntegrityException $ex) {
  // Blob does not match its recorded hash: quarantine this PHID, alert,
  // and fall back to backups. Do not silently serve the bytes.
}

Prevention

When it happens

Trigger: Blob bytes changed in the storage engine (MySQL blob, disk, S3) after write: disk corruption, manual row edits, truncated objects, or a lossy storage migration; partial writes from interrupted uploads; --begin/--end ranges are fine, the check compares full content.

Common situations: Bit rot or filesystem damage under file storage; someone edited storage rows directly; S3 object replaced/truncated; copying storage between engines with a buggy script.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/1ca787ccbffbda5c. Report an issue: GitHub.

Appendix: source

Thrown at src/applications/files/management/PhabricatorFilesManagementCatWorkflow.php:69

    $end = $args->getArg('end');

    $file->makeEphemeral();

    // If we're running in "salvage" mode, wipe out any integrity hash which
    // may be present. This makes us read file data without performing an
    // integrity check.
    $salvage = $args->getArg('salvage');
    if ($salvage) {
      $file->setIntegrityHash(null);
    }

    try {
      $iterator = $file->getFileDataIterator($begin, $end);
      foreach ($iterator as $data) {
        echo $data;
      }
    } catch (PhabricatorFileIntegrityException $ex) {
      throw new PhutilArgumentUsageException(
        pht(
          'File data integrity check failed. Use "--salvage" to bypass '.
          'integrity checks. This flag is dangerous, use it at your own '.
          'risk. Underlying error: %s',
          $ex->getMessage()));
    }

    return 0;
  }

}

View on GitHub (pinned to 5720a38cfe)