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.

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)

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.