How to file integrity monitor — validate that a restore matches the source
- Step 1Confirm a Pro plan or higher and check file sizes — The File Integrity Monitor requires Pro or above. Pro allows files up to 100 MB each, Pro-media 500 MB, and Developer 2 GB. Backup archives and database dumps are often large, so a multi-hundred-megabyte export may need Pro-media or Developer. The Free tier does not include this tool.
- Step 2Restore the file to a scratch location — Run your restore as you normally would, writing the recovered file to a working folder so you do not overwrite the live source. You now have two files to compare: the live source and the restored copy.
- Step 3Drop the source as A and the restore as B — Put the live source in file A and the restored copy in file B. The comparison is symmetric so order does not affect the verdict, but source-as-A keeps the report readable. Fewer than two files stops the run with
Drop two files to compare. - Step 4Run the comparison — On submit both files are read fully into memory and hashed with SHA-256 in parallel. Equal digests set
identical: trueandfirstDiffOffset: -1. Different digests trigger a byte-by-byte scan from offset 0 to find the first divergence. - Step 5Read the verdict and characterize any failure —
identical: truecertifies the restore matches the source — log it as a passed restore test.identical: falsemeans the restore is wrong; readfirstDiffOffset. If it equals the restored file's size, the restore is truncated. If it is mid-file, the backup media likely corrupted a block — capture the hex window for evidence. - Step 6Download the report into your DR runbook — Export integrity-report.json and file it with your restore-test records. It carries both filenames, sizes, full SHA-256 digests, the identical flag, the offset, and the hex windows — the evidence line that proves this recovery point was verified on this date.
Restore-test outcomes and what they mean
Mapping integrity-report.json results to DR conclusions. The identical flag is the pass/fail; firstDiffOffset characterizes a failure.
| Result | DR interpretation | Next step |
|---|---|---|
identical: true | Restore is byte-for-byte the source — passed restore test | Record the report as evidence; mark recovery point verified |
identical: false, firstDiffOffset == restored size | Restore is a clean prefix of the source — truncated restore | Check the backup job for an incomplete export; re-run the restore |
identical: false, mid-file offset | Block-level corruption between source and restore | Suspect failing backup media; escalate and retest from another copy |
identical: false, restore larger than source | Restore gained bytes (e.g. re-compressed or padded by tooling) | Review the backup tool's settings; raw bytes must round-trip |
Plan limits for restore validation
Pro and above only. Limits are per file; you always compare exactly two, so the per-file size is the constraint for large archives.
| Plan | Available? | Max size per file | Typical backup fit |
|---|---|---|---|
| Free | No | — | Not included; minimum is Pro |
| Pro | Yes | 100 MB | Config files, small DB dumps, document sets |
| Pro-media | Yes | 500 MB | Mid-size archives and exports |
| Developer | Yes | 2 GB | Large database dumps and disk images |
What restore validation this tool does and does not do
The File Integrity Monitor certifies byte identity. For neighbouring DR tasks, the right sibling tool is listed.
| Need | This tool | Use instead |
|---|---|---|
| Does the restored file match the source exactly? | Yes — SHA-256 of each, compared, plus first-diff offset | — |
| A multi-algorithm fingerprint of each recovery point | Computes SHA-256; needs two files to run | multi-hash-fingerprinter for md5 / sha-1 / sha-256 / sha-512 per file |
| Encrypt the verified backup before archiving offsite | No | aes-256-encryptor |
| Detect bit-rot in cold archives over time | Compares two files now; no stored baseline | multi-hash-fingerprinter to record baseline digests, then compare later |
Cookbook
Backup and DR validation scenarios with the JSON report each produces. SHA-256 digests are truncated for readability; the tool emits the full 64-hex-character value.
Pass a routine restore test
Your nightly DR drill restores a database dump to scratch and compares it to the live export. A digest match is a clean pass you can record.
file A: sales-db.dump (live source, 314,572,800 bytes)
file B: sales-db.dump (restored, 314,572,800 bytes)
integrity-report.json:
{
"fileA": { "name": "sales-db.dump", "size": 314572800, "sha256": "9f86d081...a08f" },
"fileB": { "name": "sales-db.dump", "size": 314572800, "sha256": "9f86d081...a08f" },
"identical": true,
"firstDiffOffset": -1,
"firstDiffHex": null
}
Verdict: match -> restore test passed. (Needs Pro-media for 300 MB.)Catch a truncated restore
The restore process stopped early. The restored file matches the source up to a point and then ends — firstDiffOffset equals the restored size and B's hex window is empty.
file A: archive-2026-Q1.tar (source, 209,715,200 bytes)
file B: archive-2026-Q1.tar (restored, 157,286,400 bytes)
integrity-report.json:
{
"fileA": { "name": "archive-2026-Q1.tar", "size": 209715200, "sha256": "a1b2c3d4...0011" },
"fileB": { "name": "archive-2026-Q1.tar", "size": 157286400, "sha256": "55667788...99aa" },
"identical": false,
"firstDiffOffset": 157286400,
"firstDiffHex": {
"a": "7573722f6c6f63616c2f73686172652f00",
"b": ""
}
}
Offset == restored size -> truncated restore. Re-run; check the backup job.Detect block-level corruption from failing media
Same size, but a bad block on the backup drive flipped bytes mid-file. The digests differ and firstDiffOffset lands deep in the file — the signature of storage rot, not truncation.
file A: vm-snapshot.img (source, 524,288,000 bytes)
file B: vm-snapshot.img (restored, 524,288,000 bytes)
integrity-report.json:
{
"fileA": { "name": "vm-snapshot.img", "size": 524288000, "sha256": "7d865e95...4e2a" },
"fileB": { "name": "vm-snapshot.img", "size": 524288000, "sha256": "d4735e3a...c2f1" },
"identical": false,
"firstDiffOffset": 268435456,
"firstDiffHex": {
"a": "00ff00ff00ff00ff00ff00ff00ff00ff00",
"b": "00ff00ff00ff0000000000ff00ff00ff00"
}
}
Deep mid-file divergence, same size -> corrupted block. Suspect the media.Verify a config file restored exactly
Small but critical: a single flipped byte in a restored config can break a service. The check is decisive even for tiny files.
file A: nginx.conf (source, 8,192 bytes)
file B: nginx.conf (restored, 8,192 bytes)
integrity-report.json:
{
"fileA": { "name": "nginx.conf", "size": 8192, "sha256": "2c26b46b...9a3b" },
"fileB": { "name": "nginx.conf", "size": 8192, "sha256": "2c26b46b...9a3b" },
"identical": true,
"firstDiffOffset": -1,
"firstDiffHex": null
}
Match -> the restored config is identical. Safe to put back into service.Record a verified recovery point with full audit detail
For a compliance audit you keep the integrity report plus a multi-algorithm fingerprint of the source. The report proves the restore matched; the fingerprint strengthens the baseline.
file A: ledger-2025.sqlite (source, 83,886,080 bytes)
file B: ledger-2025.sqlite (restored, 83,886,080 bytes)
integrity-report.json (filed under DR-TEST-2026-06):
{
"fileA": { "name": "ledger-2025.sqlite", "size": 83886080, "sha256": "e3b0c442...b855" },
"fileB": { "name": "ledger-2025.sqlite", "size": 83886080, "sha256": "e3b0c442...b855" },
"identical": true,
"firstDiffOffset": -1,
"firstDiffHex": null
}
Match -> recovery point verified. For md5 + sha-1 + sha-512 of the source,
also run /security-tools/multi-hash-fingerprinter on it.Edge cases and what actually happens
Restore matches the source exactly
IdenticalThe SHA-256 digests are equal, so the report returns identical: true, firstDiffOffset: -1, and firstDiffHex: null. No byte scan runs — the cryptographic match alone certifies a passed restore test. Record the report as evidence the recovery point is good.
Restore is truncated (a clean prefix of the source)
By designIf the restored file matches the source for its whole length and then ends, the scan runs out of bytes in the shorter file. firstDiffOffset is reported as the restored file's byte length and its hex window is empty. This is the signature of an incomplete restore — re-run and inspect the backup job for an early stop.
Same size but bytes differ (storage corruption)
DifferentEqual sizes never prove identical content. A bad block on the backup media can flip bytes without changing the length; the tool compares digests, not sizes, so it is caught and firstDiffOffset points to the first damaged byte. A deep, same-size divergence is the hallmark of block-level corruption rather than truncation. To examine the surrounding bytes beyond the 16-byte window, open the file in hex-header-inspector.
A backup archive exceeds your plan's per-file limit
RejectedEach file is checked against your plan's security size cap before hashing. A 1.5 GB dump on Pro (100 MB) or Pro-media (500 MB) fails with a message naming the file, its size, and the cap. Large dumps need the Developer tier (2 GB); beyond that they cannot be compared here.
Restore is larger than the source
DifferentIf the restored file gained bytes — for instance a tool re-compressed or padded it — the digests differ and it is not a prefix of the source, so firstDiffOffset is wherever the first byte mismatch occurs. A faithful raw-byte restore must round-trip exactly; investigate the backup tool's settings.
Source and restore have different filenames
ExpectedOnly bytes are hashed; filenames are recorded verbatim but never affect the verdict. A source named export.dump and a restore named export-restored.dump will still report identical: true if their bytes match. The names exist for your DR runbook, not the comparison.
You want to monitor a cold archive over months, not compare now
Out of scopeThis tool compares two files in front of you; it does not store a baseline to re-check later. To watch for bit-rot over time, record each archive's digests with multi-hash-fingerprinter and re-fingerprint periodically, comparing to the saved baseline.
Both files are empty (0 bytes)
IdenticalTwo empty files share the SHA-256 of the empty input, so the report returns identical: true with offset -1. An empty restore compared against a non-empty source differs at offset 0, since the empty file is a zero-length prefix of the other — a clear sign the restore produced nothing.
A large dump makes the tab slow during a drill
ExpectedBoth files are read fully into memory before hashing — there is no background streaming. Comparing two near-2 GB dumps uses heavy memory and pauses noticeably while the buffers load and digests compute. Run the drill with other tabs closed and avoid concurrent in-tab tools.
Fewer than two files dropped
RejectedThe tool needs exactly two files. With fewer it stops at Drop two files to compare. and produces no report. To fingerprint a single recovery point on its own, use multi-hash-fingerprinter.
Frequently asked questions
How is this better than trusting the backup job's success log?
A success log only says the job ran, not that the data restores correctly. This tool restores the question to bytes: it computes the SHA-256 of the live source and the restored copy and certifies they are byte-for-byte identical. That is the only test that catches a backup that 'succeeds' nightly but restores corrupted or truncated data.
Does my production data get uploaded to validate the restore?
No. Both files are read into the browser tab via the File API and hashed locally with the Web Crypto API (crypto.subtle.digest). Nothing is sent to a server, so production database dumps, customer data, and sealed archives never leave the machine during a DR drill.
Which hash does the restore test use?
SHA-256. The source and the restored file are each hashed with SHA-256 in parallel and the two 64-character hex digests are compared. A match means they are byte-identical; SHA-256 is collision-resistant for practical integrity verification.
How do I tell truncation from corruption when a restore fails?
Read firstDiffOffset. If it equals the restored file's byte size, the restore is a clean prefix of the source that simply ended — truncation. If it lands mid-file with the same total size, bytes were altered in place, which points to block-level corruption on the backup media. The hex window shows the damaged bytes.
Can it compare two large database dumps?
Yes, within your plan's per-file cap: Pro 100 MB, Pro-media 500 MB, Developer 2 GB each. Both files are loaded fully into memory in the tab, so very large dumps use a lot of RAM and take a noticeable moment to hash.
Can it watch my cold archives for bit-rot over time?
Not directly — it compares two files you provide now and does not store a baseline. For long-term monitoring, record each archive's digests with multi-hash-fingerprinter and re-fingerprint on a schedule, comparing each result to the saved baseline. This tool is for proving a restore matches a source today.
Why does it flag a difference when the restored file opens fine?
Because the check is byte-level, not functional. A restore can open and even mostly work while a corrupted block or a rewritten metadata field changes bytes. Any single differing byte sets identical to false. The offset and hex window reveal where the change is so you can judge its severity.
Does the order of source and restore matter?
Not for the result — the comparison is symmetric, so the verdict and offset are identical either way. Put the source as file A and the restore as file B by convention so the report reads naturally and your DR records are unambiguous.
What if the restored file is a different size than the source?
Different sizes guarantee a mismatch, so identical is false. The scan compares bytes up to the shorter file's length; if all match, the shorter file is a prefix of the longer one and firstDiffOffset is set to the shorter length (truncation, if the restore is shorter). Otherwise the offset is the first real mismatch.
Should I encrypt the verified backup before sending it offsite?
That is a separate step this tool does not perform, but the sibling aes-256-encryptor encrypts a verified file with AES-GCM-256 and PBKDF2 before you archive or ship it. Verify integrity here first, then encrypt the confirmed-good copy.
Do I need a paid plan for restore validation?
Yes. The File Integrity Monitor is a Pro-tier (and above) tool and is not on the Free plan. Pro allows 100 MB per file, Pro-media 500 MB, and Developer 2 GB. You always compare exactly two files, so the per-file size cap is the binding limit for large backups.
What do I keep as evidence a restore was verified?
Download integrity-report.json and file it with your restore-test records or DR runbook. It captures both filenames, sizes, full SHA-256 digests, the identical flag, the first-diff offset and hex windows — a self-contained record that the recovery point was verified on that date. For a multi-algorithm baseline, also run multi-hash-fingerprinter on the source.
Privacy first
Every JAD Security operation runs entirely in your browser. Files, passwords, and PGP private keys never leave your device — verified by zero outbound network requests during processing.