phacility/phabricator · critical · Exception

Integrity check failed: new file data differs from old data!

Error message

Integrity check failed: new file data differs from old data!

What it means

After converting a hunk to a new storage type, migrate-hunk reloads the hunk from the database and compares getChanges() against the original data captured before migration. Any byte difference throws this integrity exception, meaning the text->file or file->text conversion corrupted or altered the content. This is a deliberate stop-the-world check: a failure means the storage path (usually file storage for DATATYPE_FILE) is broken or lossy, and the hunk's data is now suspect.

Source

Thrown at src/applications/differential/management/PhabricatorDifferentialMigrateHunkWorkflow.php:205

        break;
      case DifferentialHunk::DATATYPE_FILE:
        $hunk->saveAsFile();
        break;
    }

    $this->logOkay(
      pht('MIGRATE'),
      pht(
        'Converted hunk %d to "%s" storage (with format "%s").',
        $hunk->getID(),
        $new_type,
        $hunk->getDataFormat()));

    $hunk = $this->loadHunk($hunk->getID());
    $new_data = $hunk->getChanges();

    if ($old_data !== $new_data) {
      throw new Exception(
        pht(
          'Integrity check failed: new file data differs from old data!'));
    }
  }


}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Check the Daemons/file storage config (phabricator.file-storage backend) and verify a test file round-trips: upload and re-download a file
  2. Inspect the affected hunk directly: compare SELECT changes against the stored file blob; re-migrate back with --to text if the text copy is intact
  3. Free disk space / fix S3 credentials or bucket policy, then re-run './bin/differential migrate-hunk --id <id> --to text' to restore textual storage
  4. If content is genuinely lost, restore the row from a backup (differential_hunk and the file blobs) and report the incident upstream with the hunk ID and formats involved
  5. Before bulk migrations, always run a --dry-run pass and keep database + file-storage backups

Example fix

// Not a code fix: this exception indicates data corruption, not API misuse.
// Recovery sequence:
// 1) ./bin/storage dump --out backup.sql  (or restore point)
// 2) Inspect: SELECT id, dataType, dataFormat, changes FROM differential_hunk WHERE id = <id>;
// 3) If file-backed copy is corrupt, re-migrate the hunk back:
//    phabricator/ $ ./bin/differential migrate-hunk --id <id> --to text
// 4) Fix the underlying file-storage configuration before retrying --to file.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before any --to file migration, verify file storage round-trips
$test = PhabricatorFile::newFromFileData('integrity-probe-'.time(), array('name' => 'probe.txt'));
if ($test->loadFileData() !== 'integrity-probe-'.time()) {
  throw new Exception('File storage backend is not round-trip safe; abort migration.');
}

Try / catch

foreach ($hunk_ids as $id) {
  try {
    // migrate one hunk at a time so a failure isolates to a single row
    // ./bin/differential migrate-hunk --id $id --to file
  } catch (Exception $ex) {
    // Integrity failure: STOP the batch, snapshot/backup the affected hunk,
    // re-migrate that hunk back with --to text, and investigate file storage.
  }
}

Prevention

When it happens

Trigger: Migrating to DATATYPE_FILE while the Phabricator file storage engine (local disk path or S3/blob backend) is misconfigured, truncating or mangling writes; character-set or escaping corruption on the text path; a partial/interrupted write leaving the hunk half-migrated; bugs in the hunk data-format (compression) round-trip for a specific content shape.

Common situations: Storage migrations to S3 with wrong credentials or bucket settings producing empty objects; local file storage directory not writable or full; migrating very large hunks that hit body-size or memory limits; moving between MySQL text columns with differing charset settings.

Related errors


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