phacility/phabricator · critical · PhabricatorFileIntegrityException

File data integrity check failed. Dark forces have corrupted

Error message

File data integrity check failed. Dark forces have corrupted or tampered with this file. The file data can not be read.

What it means

Before serving file data, PhabricatorFileStorageEngine::getRawFileDataIterator() recomputes the integrity hash over the stored (formatted) bytes and compares it to the hash recorded at write time with phutil_hashes_are_identical(). A mismatch raises PhabricatorFileIntegrityException: the bytes in storage differ from what was written — corruption, truncation, or the data being read through a different format/key material than it was written with. Note the AES-256 format folds the per-file IV into the integrity hash, so format/property drift also trips this check.

Source

Thrown at src/applications/files/engine/PhabricatorFileStorageEngine.php:342

      return null;
    }

    return $engine->getChunkSize();
  }

  public function getRawFileDataIterator(
    PhabricatorFile $file,
    $begin,
    $end,
    PhabricatorFileStorageFormat $format) {

    $formatted_data = $this->readFile($file->getStorageHandle());

    $known_integrity = $file->getIntegrityHash();
    if ($known_integrity !== null) {
      $new_integrity = $this->newIntegrityHash($formatted_data, $format);
      if (!phutil_hashes_are_identical($known_integrity, $new_integrity)) {
        throw new PhabricatorFileIntegrityException(
          pht(
            'File data integrity check failed. Dark forces have corrupted '.
            'or tampered with this file. The file data can not be read.'));
      }
    }

    $formatted_data = array($formatted_data);

    $data = '';
    $format_iterator = $format->newReadIterator($formatted_data);
    foreach ($format_iterator as $raw_chunk) {
      $data .= $raw_chunk;
    }

    if ($begin !== null && $end !== null) {
      $data = substr($data, $begin, ($end - $begin));
    } else if ($begin !== null) {
      $data = substr($data, $begin);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. If storage-format settings, keyring keys, or encryption were changed, re-encode affected files with Phabricator's storage format migration tooling instead of forcing reads
  2. Compare the stored object against a known-good copy or backup to confirm real corruption, and restore the good copy
  3. Never modify stored file data in place; if a file is unrecoverable, remove its record explicitly rather than serving altered bytes
  4. Audit per-file storage properties (format, iv/payload) for the affected files to rule out metadata corruption
Defensive patterns

Strategy: try-catch

Try / catch

catch PhabricatorFileIntegrityException specifically; do not retry (deterministic), never serve the bytes anyway, alert operators, and return an explicit 'file corrupted' response.

Prevention

When it happens

Trigger: Stored blob bytes were altered or truncated (disk/S3/database); files written unencrypted are read through the AES-256 format or vice versa; per-file storage properties (iv.base64/payload.base64) were mangled; the integrity hash column was hand-edited.

Common situations: Bit rot or a partially failed disk; operators editing stored blobs in place; enabling at-rest encryption or cycling keys without running the storage format migration; restoring storage backends from mismatched snapshots.

Related errors


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