Recover data from a corrupted Firebird database
Your Firebird database stopped opening, a query fails with internal Firebird consistency check, or gbak cannot back it up. This page is the order of steps that saves the most data, from the least to the most drastic. The error pages explain what the common messages mean.
First: make a copy, and work only on the copy
Stop the Firebird server, or at least make sure nothing is connected to the database. Then copy the file, together with any .delta file next to it (an nbackup lock) and the secondary files of a multi-file database. A copy taken while the server writes to the file is inconsistent, and every repair attempt changes the file it runs on. If the disk itself is failing, copy the file to another disk before anything else.
Then: try Firebird’s own tools
These come with every Firebird installation and often get a database back as a whole: indexes, triggers, users and all. On the copy:
gfix -v -full -n copy.fdb # validate, report only
gfix -mend -full -ignore copy.fdb # let gbak skip damaged records
gbak -b -v -ig -g copy.fdb copy.fbk # back up: no checksums, no GC
gbak -c -v copy.fbk restored.fdb # restore into a new database
Add -user SYSDBA -password ... as your server needs. If gbak -b completes, the restored database is the result: check the row counts of the important tables. gfix -mend throws away the records it cannot read, so compare with the original before you rely on the restored copy.
If gbak still fails: get the data out with fbrescue
fbrescue reads the database file directly, without the Firebird engine, and exports every row it can read. It does not stop at the first damaged record or page, and it never writes to the file. Download the single binary for your system from Releases (Windows, Linux, macOS; nothing to install).
fbrescue scan copy.fdb # what is damaged, by table
fbrescue export copy.fdb --out rescued --format sql # schema.sql + INSERTs per table
--format csv and --format jsonl are there too. Rows that could not be read are listed in rescued/_errors.jsonl with the page and the reason, and the exit status is 2 when anything was left out. To load the result into a new database:
isql -ch UTF8 -i rescued/schema.sql new.fdb
isql -ch UTF8 -i rescued/CUSTOMERS.sql new.fdb # and so on for each table
If you would like help, open an issue and attach the output of fbrescue report copy.fdb: it describes the damage without any of your data, and with table and column names replaced by numbers.
What fbrescue does with damage
- Damaged records: skipped and listed; the rest of the table is exported.
- Damaged or zeroed pages: the rows on them are lost, the rest of the database is not. Data pages that the table’s pointer pages no longer reach are found by reading the whole file.
- Pages in the wrong place (Firebird 3 and later store each page’s number on the page): read from where they are.
- Damaged transaction inventory (
cannot find tip page): rows are still exported; where a transaction’s state is lost, the newest version is taken, with a warning. - Damaged header page: the page size and version come from the rest of the file.
- Lost table definitions: tables and columns come out under made-up names (
TABLE_131,FIELD_2). If the record layouts themselves are lost, give fbrescue the CREATE TABLE statements of your database (--ddl schema.sql): the script that created it,isql -xoutput, or an earlier fbrescue export.
How much comes back from each kind of damage is measured on hundreds of damaged copies of a test database on Firebird 2.5, 3.0, 4.0 and 5.0: see the recovery rate.
fbrescue gets the data out; it does not repair the file in place. Indexes, triggers, procedures and users are not exported: create them again in the new database. How it compares with gfix/gbak and IBSurgeon FirstAID: comparison; short answers: FAQ.
Not damaged, just no Firebird to open it?
The same tool exports intact databases: open a .fdb file without Firebird, export to CSV or Excel, move the data to PostgreSQL.
Common errors
internal Firebird consistency check (decompression overran buffer (179))— a record’s bytes are damagedinternal Firebird consistency check (wrong record length (183))— a record does not match its table’s layoutinternal Firebird consistency check (cannot find tip page (165))— the transaction inventory is damageddatabase file appears corrupt/page is of wrong type— a page holds something other than it shouldI/O error during "read" operation— the file is shorter than the database, or the disk failsgbak: ERROR…Exiting before completion due to errors— the backup of a damaged database stops