SUBMIT A FILE TYPE CONTACT US SUPPORT ABOUT US

What Is an MDB File? A Database Made of Pages, and How Readers Handle Broken Ones

An MDB file is a Microsoft Access database, so copy it before you open it. Jump to your question below, or work through it in order.

42 min read Updated October 2026 Checked against sources and tests

What Is an MDB File? An Access database in the format of Access 2003 and older

Short answer

MDB files end in .mdb, and one is a Microsoft Access database in the format of Access 2003 and older. It stores tables and rows in one binary file made of fixed size pages. Access 2007 and later write the newer ACCDB file by default.

We read 43 public MDB files, and we damaged 15 of them in 19 ways to make 495 copies. On 22 copies the reader printed other data and no message, and on 173 copies the file command still said Access database.

To see the parts, go to the inside part. To check an MDB file, follow the six steps. To judge risk, read the safety part.

An MDB file is a Microsoft Access database in the format of Access 2003 and older, and its name ends in .mdb. It stores tables and rows in one binary file made of fixed size pages. Access 2007 and later write the newer ACCDB file by default.

Wikipedia’s article on Microsoft Access calls MDB the format of Access 2003 and earlier. Microsoft’s page on Access file formats says ACCDB has been the default since Access 2007. It says MDB stays in use for older versions of Access, for replication and for user level security.

The Library of Congress says Microsoft has never published a specification for the format. Its record for the MDB family names two reverse engineered descriptions and says later versions of Access, up to 2016, can still save MDB files.

Why one name covers two engines

Two database engines write MDB files. Jet 3 comes from Access 95 and 97, and Jet 4 comes from Access 2000 to 2003. Wikipedia’s article on Jet says Jet 4 added Unicode text, a decimal type and record level locking. It also says Jet 4 pages data in 4 kB units where the older engine used 2 kB.

The two kinds of MDB file start with the same bytes. One byte at offset 20 separates them, and the versions part shows it. Newer Access versions use the ACE engine, which also reads an MDB file, says Wikipedia’s article on the Access Database Engine.

Where our MDB files come from

We read 43 public MDB files from the test data of Jackcess, an open source Java library for Access files that uses the Apache 2.0 license. These MDB files contain no private data. They add up to 37,580,800 bytes, 163 tables and 270,833 rows. 9 of the MDB files are Jet 3 files.

We copied one small file from that set, with 1 table and 512 rows, and called it sample.mdb. We damaged 15 of the 43 in 19 ways, which gave 495 damaged copies. We also read 42 ACCDB files from the same folders, so we could compare their version bytes with those of the MDB files.

We read every MDB file with mdbtools 1.0.0, an open source reader for Access files. The file command 5.45 named the type, Python 3.13 and SQLite 3.45.1 did the conversions, and our own scripts checked the structure. We did not use Microsoft Access.

MDB file facts at a glance

Quick facts about MDB files
Property Value
Meaning A Microsoft Access database. It stores tables and rows in one binary file.
Made by Microsoft Access 2003 and older, and any program that writes the Jet format. Access 2007 and later can still save MDB files.
Format Binary, in fixed size pages. Microsoft has published no specification, says the Library of Congress.
Start The bytes 00 01 00 00, then the text Standard Jet DB and a zero byte. All 43 of our public MDB files start that way.
Version byte Byte 20. It is 0 for Jet 3 and 1 for Jet 4 in our 43 MDB files.
Page size 2,048 bytes in Jet 3 and 4,096 bytes in Jet 4.
Size limit 2 GB minus the space of system objects, says Microsoft, for .mdb and .accdb files.
Opens with Microsoft Access. Free tools like mdbtools and viewers from SysTools and Freeviewer also read it.
Size in our set 65,536 to 10,514,432 bytes, with a median of 229,376 bytes.
Our tests 43 public MDB files, 495 damaged copies, one reader, a row count check and a 75 line script.

Wrong page? Look at the ACCDB page for the newer Access format, the MDF page for SQL Server data files or the SQLITE page for SQLite databases.

What Is Inside an MDB File? A header, fixed size pages and a catalog on page 2

An MDB file is a list of fixed size pages. Page 0 is the header, and it starts with four set bytes and the text Standard Jet DB. Page 2 is the catalog, which lists the tables.

The figure cuts our 241,664 byte sample MDB file into its 59 pages and colors them by type. Below it are the first 24 bytes, which are the same in every Jet and ACE file we read.

A strip of 59 cells, one for every 4,096 byte page of a 241,664 byte MDB file, colored by page type, and a close-up of the first 24 bytes of page 0 that name the engine and the version. The file has 28 data pages, 10 table definition pages, 1 index page, 18 index leaf pages, 1 page of type 8 and the header page.
One MDB file of 59 pages. Page 0 is the header, and page 2 is the catalog.
The first 24 bytes of our MDB file, shown by xxd
00000000: 0001 0000 5374 616e 6461 7264 204a 6574  ....Standard Jet
00000010: 2044 4200 0100 0000                       DB.....

The header page of an MDB file

The first four bytes of an MDB file are 00 01 00 00. Then come the text Standard Jet DB and a zero byte. Byte 20 is the version byte, and the three bytes after it are zero in our file. PRONOM’s record for the Access 2002 format lists the same 24 bytes as the signature.

The 42 ACCDB files we read say Standard ACE DB in the same place. The version byte is the first sign of which engine wrote an MDB file, and a scrambled name or byte is a sign of damage.

The next 128 bytes of the header are scrambled with a fixed RC4 mask, says the source of mdbtools. The mask is the four bytes C7 DA 39 6B. Once undone, the bytes give the code page, the sort order, a database code and the build number of the engine.

Our sample has code page 1252, sort order 0x0409, a database code of 0 and build 9025. A database code that is not 0 means the pages are encrypted, says mdbtools. None of our 43 public MDB files is encrypted.

Pages, types and the catalog

Every page after the header starts with a type byte and a second byte of 1. Type 1 is a data page, type 2 is a table definition and type 3 is an index. Type 4 is an index leaf.

Our 43 MDB files also have 14 pages of type 8 and 13 of type 9, which we did not study.

The catalog is a table named MSysObjects, and its definition is always page 2, says mdbtools. Our sample has 21 entries in it. They name the tables, queries and other objects of the database, and a reader needs page 2 before it can find anything else in the MDB file.

Tables and rows in an MDB file

Our sample has one table, Table1, with the columns CD_AGENTE, RS_AGENTE and DC_AGENTE and 512 rows. The first row is 19,"abc","def". Two numbers describe those rows. The table definition stores a row count, and the data pages store the rows.

The mdb-count command prints the stored count, and mdb-export reads the rows themselves. When the two numbers differ, a page of the MDB file is gone or damaged. The check part uses that as a test.

What Microsoft says about the limits

Microsoft’s Access specifications list the limits that apply to .accdb and .mdb files. A database is 2 GB minus the space of system objects. It has up to 255 users at once, 32,768 objects, 255 fields in a table and 32 indexes in a table.

We read this layout from one small MDB file, 43 public MDB files and the documents named above. We did not use Microsoft Access, so it can read some of these parts in other ways.

Which Access Versions Write MDB Files? Jet 3, Jet 4 and one byte that names them

Byte 20 of the file names the engine. It is 0 for Jet 3 (Access 95 and 97) and 1 for Jet 4 (Access 2000 to 2003). ACCDB files use 2 and higher. Our 43 public MDB files use only 0 and 1.

The figure lists the seven values that we know and how many of our 85 files use every value. The 85 are our 43 MDB files and 42 ACCDB files from the same folders.

A table of the version byte of an MDB or ACCDB file, from 0 to 6, with the engine name, the Access releases, the page size and the number of MDB and ACCDB test files with that byte. All 43 MDB files have byte 0 or byte 1.
One byte at offset 20 names the engine. Our 43 public MDB files use only the first two values.

MDB or ACCDB in Microsoft Access

Microsoft’s page says ACCDB adds multivalued fields, the attachment type, SharePoint and Outlook integration, stronger encryption and an append only history. Calculated fields arrived with Access 2010. It says MDB files in the Access 2000 and Access 2002 to 2003 formats open normally in newer versions of Access.

The same page says user level security, which only MDB files support, is no longer effective for data security. Keep that in mind if an old MDB file relies on it.

Jet and ACE versions

Wikipedia’s table pairs Access 97 with Jet 3.5 and Access 2000 with Jet 4.0. It pairs Access 2007 with ACE 12, Access 2010 with ACE 14, Access 2013 with ACE 15 and Access 2016 with ACE 16. It does not list Access 2019. Jet was a 32 bit engine, and Wikipedia says Microsoft calls it deprecated.

Our version byte list follows the source of mdbtools and Microsoft’s table. Our test folders had no file with byte 4 or 5, so we did not read those values ourselves. Our one ACCDB file with byte 6 matches the Access 2019 row of the figure.

What this means for your MDB file

Read byte 20 of an MDB file before you choose a tool. A Jet 3 file has 2,048 byte pages and a Jet 4 file has 4,096 byte pages, so a tool that expects one size can fail on the other.

The version byte is also the first thing that damage changes in an MDB file, and the damaged part shows what happens then.

What Do 43 Public MDB Files Contain? 270,833 rows, no warnings and 40 files that convert

We read 43 public MDB files with mdbtools. They contain 163 tables and 270,833 rows. The reader printed no warning on any of them, every stored row count matched the rows we exported, and our script flagged none.

The 43 are test files from the Jackcess project, so they show how a test suite builds MDB files and not every file you can find. The table sorts the 43 MDB files by the folder they come from.

43 public MDB files
270,833 rows to read
37.6 MB of data to read
495 damaged copies
The 43 public MDB files by folder
Folder What is in it
V1997 9 files, all Jet 3, with 2,048 byte pages.
V2000 16 files, all Jet 4, with 4,096 byte pages.
V2003 17 files, all Jet 4, with 4,096 byte pages.
One more file adox_jet4.mdb is a Jet 4 file with no tables.

What the MDB files show

Sizes range from 65,536 to 10,514,432 bytes, with a median of 229,376 bytes. The two biggest MDB files both have 133,792 rows. 10 of the 43 MDB files have no rows at all. Together the 43 files have 9,477 pages.

42 of the 43 use code page 1252, and one, testTurkishV2003.mdb, uses 1254. None of them is encrypted.

What the reader and our scripts did with the MDB files

mdbtools printed no warning for any of the 43 files. For every table, the stored row count matched the rows that mdb-export printed. Our 75 line script flagged none of the 43 MDB files, and it read all of them in under a tenth of a second.

The same script flagged none of the 85 intact files we read, and 43 of them are MDB files. They are our 43 MDB files and 42 ACCDB files. That is a low bar, because we tuned the rules on these files, so we tested it on damaged copies as well.

Turning the 43 MDB files into SQLite

We also converted all 43 MDB files with mdbtools and Python. 40 files worked and gave 270,830 rows in SQLite. The three that failed are the three test2 files, one in every folder. SQLite stopped on a NUL byte inside a value of the table MSP_PROJECTS.

That is a limit of the route and not a proof that the files are damaged. mdbtools read all three MDB files, and our row count check found no mismatch in them.

The 15 MDB files we damaged

We selected 15 of the 43 MDB files for the damage tests. All 15 have rows. They range from 65,536 to 10,514,432 bytes and come from three folders. Every file got 33 damaged copies, so the figure shows 495 copies.

A table of 15 public MDB files with their version, size, tables and rows, and a bar for every file that splits its 33 damaged copies into four groups: the same data, other data with a message, other data with no message and no data.
15 public MDB files and what happened to their 495 damaged copies.

Every bar splits the 33 copies of one MDB file into four groups. The two files with 133,792 rows kept the same data in only 3 of 33 copies. The small MDB files kept it in up to 25 copies.

Big files lose more The two 10 MB files kept the same data in only 3 of 33 copies.
Small files lose less A file of 11 rows kept the same data in up to 25 of 33 copies.
Some copies printed nothing 80 of the 495 copies gave no data, and mdbtools said why in 79 of them.
Some copies said nothing 22 of the 495 copies printed other data and no message.

What the numbers do not show about MDB files

We read the MDB files with one reader, and we did not use Microsoft Access. The MDB files come from a test folder. A database that has grown for ten years, with forms, macros and attachments, can behave in other ways. We cannot say how Access reads our damaged copies.

What Happens When an MDB File Is Damaged? 495 copies, and 22 that printed other data in silence

We damaged 15 MDB files in 19 ways and read all 495 copies of them with mdbtools. 242 copies printed the same data, 151 printed other data with a message, 22 printed other data and no message and 80 printed nothing. The file command called all 173 copies with other data an Access database.

We changed one thing in an MDB file at a time and sorted the 19 kinds into five groups. They cover the header, files that are cut or extended, system pages, data pages and single bytes. Kinds that choose a random spot got more seeds, so they have 30 or 45 copies.

We read every copy with mdb-ver, mdb-tables, mdb-count and mdb-export. We compared what mdb-export printed with what it printed for the intact file. A message is any text a command wrote about a problem. A name like k13.mdb in a code box is a copy of kind 13 in the figure.

A table of 19 kinds of damage in five groups, with a bar for every kind that splits the copies into the same data, other data with a message, other data with no message and no data. Two columns count the copies flagged by our script and by the row count check.
495 damaged copies in 19 kinds. The last two columns count what our two checks flagged.

Green means the same data. Amber means other data and a message. Red means other data and no message, which we call silent. Gray means no data. The last two columns count what our script and the row count check flagged.

Silent damage in an MDB file

22 copies printed other data and no message. Two of them are cuts at 10 percent of the size. Nine have a zeroed data page, and 11 have changed bytes. 126 of the 173 copies with other data had an exit code of 0 on every command, so a script that checks the exit code sees success.

The file command did not help with a damaged MDB file. It named all 173 copies with other data a Microsoft Access Database. It said data for 30 copies only, and those are the 15 with a zeroed header page and the 15 with a changed engine name.

How many rows an MDB file loses

Of the 173 copies with other data, 148 printed fewer rows than the intact MDB file. They lost 40.3 percent of the rows on average, and the median is 17.3 percent. 12 of those 148 gave no message.

18 copies printed the same number of rows with other content, and 10 of them gave no message. 7 copies printed more rows than the intact file. One file with 11 rows gave 779. 17 copies listed no tables at all.

Header damage in an MDB file

A zeroed header page, the version byte 7F and the other version byte all stopped mdbtools on 45 of 45 copies of the MDB file. For the byte 7F it says Unknown Jet version: 7f and Couldn’t open database. Changing Standard Jet DB to Xtandard Jet DB stopped nothing. All 15 copies printed the same data.

Scrambling 8 header bytes gave 19 copies with the same data and 11 refused copies. A refusal from one reader is not proof that an MDB file lost its rows. Try a second tool before you decide.

Cut and extended MDB files

A cut at 90 percent of the size, on a page edge, left 10 of 15 copies with the same data. A cut at 50 percent left 1 of 15, and a cut at 10 percent left none. 7 printed other data with a message, 2 printed other data with no message and 6 were refused.

100 junk bytes added at the end changed nothing. All 15 copies printed the same data. Our script flags them anyway, because the size is no longer a multiple of the page size.

mdbtools and our script on a copy cut at 10 percent, on a page edge
$ mdb-tables -1 k8.mdb; echo "exit code $?"
offset 24576 is beyond EOF
mdb_read_table: Unable to find page row 1536
Unable to read table MSysObjects
File does not appear to be an Access database
exit code 1
$ python3 mdb_peek.py k8.mdb
k8.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 5 pages, 20,480 bytes
  pages after the header: 1 data, 3 table definition
  no problem found

The script says no problem for this copy. A cut on a page edge leaves valid pages, so the structure looks fine. Only the size or the hash of the MDB file, compared with the source, shows the loss.

System pages in an MDB file

When page 2 is zeroed, mdbtools cannot find any table. All 15 copies were refused with a message about page 2. The wording, File does not appear to be an Access database, points at the MDB file and not at the one page that is bad.

mdbtools and our script on a copy with page 2 zeroed
$ mdb-tables -1 k11.mdb; echo "exit code $?"
mdb_read_table: Page 2 [size=4096] is not a valid table definition page (First byte = 0x00, expected 0x02)
Unable to read table MSysObjects
File does not appear to be an Access database
exit code 1
$ python3 mdb_peek.py k11.mdb
k11.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 59 pages, 241,664 bytes
  pages after the header: 1 empty, 28 data, 9 table definition, 1 index, 18 index leaf, 1 type 8
  page 2 is not a table definition page (its type is 0)

Zeroing the other table definitions is quieter. All 15 copies printed other data with a message. Neither check flagged any of them. A page of zeros looks like an empty page, so our script cannot see it in an MDB file either.

Damaged data pages in an MDB file

Zeroing one data page gave the same data in 23 of 45 copies, other data with a message in 17 and other data with no message in 5. Zeroing 5 percent of the data pages gave 16, 10 and 4 of 30.

The count check flagged 20 of the 22 changed copies in the first kind and 11 of the 14 in the second.

Our script flagged all 45 copies with one data page filled with junk and all 45 with a changed type byte. 23 of the first and 30 of the second still printed the same data.

The row count check on a copy with one data page zeroed
$ mdb-export k13.mdb Table1; echo "exit code $?"
CD_AGENTE,RS_AGENTE,DC_AGENTE
exit code 0
$ mdb-count k13.mdb Table1
512
$ sh mdb_count_check.sh k13.mdb
Table1: stored count 512, export 0, DIFFERENT
$ file k13.mdb
k13.mdb: Microsoft Access Database

Here mdb-export prints the header line and no rows, and the exit code is 0. mdb-count still says 512. The count check names the table and the two numbers. The file command says Access database.

A few changed bytes in an MDB file

Changing 1 byte in a data page of an MDB file changed the printed data in 8 of 45 copies, and 5 of those 8 gave no message. Changing 10 bytes changed 14 of 45, with 5 silent. Changing 100 bytes changed 32 of 45, with 1 silent, and 1 more copy was refused.

Of the 80 copies that printed nothing, 79 were refused with a message and one made mdb-export loop. We stopped that loop and counted the copy as no data.

What our two checks catch in an MDB file

The row count check flagged 104 of the 173 copies with other data, and 9 of the 22 silent ones. It flagged none of the 242 copies with the same data. The 75 line script flagged 41 of the 173, and none of the silent ones.

The script flags damage in the MDB file, and the count check flags damage in the rows. Either check flagged 117 of the 173 copies, and neither flagged 56. The script also flagged 93 of the 242 copies with the same data, like the cut inside a page and the appended junk.

Two checks on two other copies
$ sh mdb_count_check.sh k14.mdb
warning: page 19 from map doesn't match: Type=0, buf[4..7]=0 Expected table_pg=15
Table1: stored count 512, export 361, DIFFERENT

$ sh mdb_count_check.sh k15.mdb
Table1: 512 rows, ok
$ python3 mdb_peek.py k15.mdb
k15.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 59 pages, 241,664 bytes
  pages after the header: 27 data, 10 table definition, 1 index, 18 index leaf, 1 type 8, 1 type 180
  page 26 has type 180, which none of our 85 intact files has

What the groups show

Results by group of damaged MDB files
Group What we found
A. Header (1 to 5) 90 copies of the MDB file. 56 were refused and 34 printed the same data. The engine name change and 19 of the 30 scrambled copies were read as if nothing happened.
B. Cut or extended (6 to 10) 75 copies. 36 printed the same data, 31 printed other data with a message and 2 printed other data with no message. 6 were refused.
C. System pages (11 and 12) 30 copies. A zeroed page 2 refused all 15. Zeroed table definitions gave other data on all 15, and no check flagged them.
D. Data pages (13 to 16) 165 copies. 92 printed the same data, 62 printed other data with a message and 9 printed other data with no message. 2 were refused.
E. Single bytes (17 to 19) 135 copies. 80 printed the same data, 43 printed other data with a message and 11 printed other data with no message. 1 was refused.

Read the grid with care. Green cells mean the same data as the intact file. We used one reader, and we did not use Microsoft Access, so a copy that mdbtools reads can still fail in Access. Every test changed one thing in a small file.

What Does Our Expert Say About MDB Files? A note from Neeraj Singh on trusting a database with care

Copy an MDB file before you open it, and keep the original. Access opens a database and can change it, and many tools read a damaged file without a word. Our test shows 22 copies that printed other data and no message.

Neeraj Singh

Expert insight

An MDB file is a database made of pages, and a few damaged pages can cost rows without a word. In our test the file command called all 173 copies that printed other data an Access database, and 22 of them printed no message. Copy the file first, hash it and compare two row counts before you trust a table.

Neeraj Singh Manager, Tech Support & Operations 19+ years fixing Windows and system errors

Why an MDB database needs care

People think a database file is safe because they only look at it. An MDB file is a set of pages that point at one another. One bad page can hide rows, and the tool that reads it can still exit with a code of 0.

Access adds a second risk, because it can change a database. Open a copy and not the original. Read the copy with a second tool, compare the row counts and add a script that checks the structure.

Keep the original. Copy the MDB file before you open it, and write down its SHA256 hash. The hash shows which file you received and whether a later copy differs.

How Do You Open an MDB File? Access, mdbtools, a viewer or a driver

Microsoft Access opens an MDB file. Without Access, read one with the free mdbtools or with a viewer from SysTools or Freeviewer. Copy the MDB file before you open it.

We read MDB files on Linux with mdbtools. We did not use Microsoft Access or the two viewers. The facts about them come from Microsoft’s pages and from the pages of the two vendors.

Open an MDB file in Microsoft Access

Microsoft’s file format comparison says MDB files in the Access 2000 and Access 2002 to 2003 formats open normally in newer versions of Access. The Library of Congress adds that versions up to 2016 can still save MDB files. We did not test any of this.

Open a copy and not the original. Access can show a Message Bar when it disables content, and the part on safety says what to do with it.

Install the Access Database Engine

Other programs read an MDB file through a database driver. Microsoft’s download page for the Access Database Engine 2016 Redistributable says it reads .mdb and .accdb files. It also says support ended on 14 October 2025, and it points to the Microsoft 365 Access Runtime as the replacement.

Wikipedia’s article on the engine says the 64 bit ACE 2010 driver is a redistributable too. We installed neither driver, so we cannot say which one your program needs.

Open an MDB file with mdbtools

mdbtools is a set of command line programs that read Access files and write nothing back. We used version 1.0.0. The first command names the engine, and the second lists the tables, one name on every line. The third prints the stored row count, and the fourth prints the rows as CSV.

Four mdbtools commands on our sample MDB file
$ mdb-ver sample.mdb
JET4
$ mdb-tables -1 sample.mdb
Table1
$ mdb-count sample.mdb Table1
512
$ mdb-export sample.mdb Table1 | head -4
CD_AGENTE,RS_AGENTE,DC_AGENTE
19,"abc","def"
27,"abc","def"
35,"abc","def"

mdb-ver printed JET4, which matches byte 20 of the file. mdb-count printed 512, and mdb-export printed the header line and the first three rows. We used these four commands to read all 495 damaged copies.

Open an MDB file with a viewer

Two vendors list viewers for MDB files on Windows. We tested neither, and both pages come from the vendors.

SysTools Free MDB Viewer

Read MDB and ACCDB files on Windows without Access

Free version previews only

Freeviewer MDB Viewer

Read MDB files on Windows without Access

Free version previews only

The SysTools page lists Free MDB Viewer, version 13.0 and 6.72 MB. It opens MDB and ACCDB files without Access, and it names Access 2003 to 2019 and Windows 7 to 11. The page says the free version only previews the data. It lists a Pro edition at $69.

The Freeviewer page lists MDB Viewer, version 3.3 and 568 KB, for MDB files only. It says the free version previews the data and the full edition costs $69. It names Windows XP to 10 in 32 and 64 bit and Windows Server. It says the tool needs .NET 4.5.

Other programs that open an MDB file

FileInfo’s page on .mdb files lists Access 365, SAS, Mathematica, Visual Studio 2022, Aryson Access Database Recovery, MDB Admin and MDB Viewer Plus for Windows. For a Mac it lists MDB Viewer and Mathematica. For Linux it lists Kexi, SAS, mdb-export and Mathematica.

The same page lists a second kind of .mdb file, an Avid Media Database. It is not an Access database, and the causes part shows how to separate them.

How the tools did on our damaged MDB files

Every tool gets its own row below. The numbers cover our 495 damaged copies of the MDB files, and the 173 are the copies that printed other data.

How every tool did on our damaged MDB files
Tool On our damaged copies
mdbtools 1.0.0 Printed the same data on 242 copies and other data on 173. 22 of those 173 came with no message. It printed nothing on 80 copies.
file 5.45 Named all 173 copies with other data a Microsoft Access Database. It said data for 30 copies only.
Row count check Flagged 104 of the 173 copies with other data, and 9 of the 22 silent ones. It flagged none of the 242 copies with the same data.
Our 75 line script Flagged 41 of the 173 copies with other data, and none of the 22 silent ones. It flagged none of the 85 intact files.
Python and SQLite Converted 40 of the 43 public MDB files, with 270,830 rows. We did not convert the damaged copies.

How Do You Check an MDB File? Six steps and two short scripts

Check an MDB file in six steps. Hash it, read its first 24 bytes, name its engine, compare the row counts and use our script to read the structure. No check proves that every row is right.

The six steps to check an MDB file

  1. Copy the MDB file, write down its SHA256 hash and work on the copy.
  2. Read the first 24 bytes with xxd -l 24 mydata.mdb. They should start with 00 01 00 00 and the text Standard Jet DB. All 43 of our public MDB files do.
  3. Name the engine with mdb-ver mydata.mdb. It printed JET4 for our sample. The file command is no help here, because it named all 173 damaged copies with other data an Access database.
  4. Compare the stored row count of every table with the rows mdb-export prints. The count script below does it for you.
  5. Use the 75 line script below. It reads the pages and names every fault it can see.
  6. Stop if a check names a fault, if two tools disagree or if the MDB file did not come from a source you trust. Get the original again.
Three commands that read our MDB file and change nothing
$ sha256sum sample.mdb
f0a1534fc68273a35272193f9c0fad5a1d1ad48d3cfbd42eee32f2ac44179def  sample.mdb
$ xxd -l 24 sample.mdb
00000000: 0001 0000 5374 616e 6461 7264 204a 6574  ....Standard Jet
00000010: 2044 4200 0100 0000                       DB.....
$ file sample.mdb
sample.mdb: Microsoft Access Database
$ wc -c < sample.mdb
241664

The count script for MDB files

The script below does step 4 for an MDB file. For every table it asks mdb-count for the stored row count and counts the rows that mdb-export prints. When the two numbers differ, it says DIFFERENT. It changes no file and starts nothing.

mdb_count_check.sh
#!/bin/sh
# mdb_count_check.sh: compare the row count stored in every table with the rows mdb-export prints.
f="$1"
for t in $(mdb-tables -1 "$f"); do
  a=$(mdb-count "$f" "$t")
  b=$(mdb-export "$f" "$t" | grep -v '^[[:space:]]*$' | python3 -c 'import csv,sys; print(max(len(list(csv.reader(sys.stdin))) - 1, 0))')
  if [ "$a" = "$b" ]; then echo "$t: $a rows, ok"; else echo "$t: stored count $a, export $b, DIFFERENT"; fi
done

On our sample it prints Table1: 512 rows, ok. On a copy with one data page zeroed the answer changes, and the exit code of mdb-export is still 0.

The count script on our sample and on a damaged copy
$ sh mdb_count_check.sh sample.mdb
Table1: 512 rows, ok

$ mdb-export k13.mdb Table1; echo "exit code $?"
CD_AGENTE,RS_AGENTE,DC_AGENTE
exit code 0
$ mdb-count k13.mdb Table1
512
$ sh mdb_count_check.sh k13.mdb
Table1: stored count 512, export 0, DIFFERENT
$ file k13.mdb
k13.mdb: Microsoft Access Database

The script flagged 104 of the 173 copies with other data, and it flagged none of the 242 copies with the same data. Copies with a message from mdbtools are the easy ones. The hard ones are the 9 silent copies that it flagged, and the 13 that it did not.

The count script on two more damaged copies
$ sh mdb_count_check.sh k14.mdb
warning: page 19 from map doesn't match: Type=0, buf[4..7]=0 Expected table_pg=15
Table1: stored count 512, export 361, DIFFERENT

$ sh mdb_count_check.sh k19.mdb
warning: Invalid data location detected in mdb_crack_row. Table:MSysObjects Column:14
Warning: mdb_col_to_string called on unsupported data type 52.
warning: Invalid data location detected in mdb_crack_row. Table:MSysObjects Column:14
Warning: mdb_col_to_string called on unsupported data type 52.
... and 6 more lines

The 75 line script that reads MDB files

The Python script below does step 5. It checks the first four bytes and the engine name, and it undoes the header mask to read the database code. It checks that the size is a multiple of the page size and that page 2 is a table definition. Then it checks the type of every page and its second byte.

The script names every fault it finds, and it changes no file. It skips the page checks when the database code is not 0, because the pages are then encrypted. Its rules come from our 85 intact files, so it knows the faults we tested and no others.

mdb_peek.py
#!/usr/bin/env python3
"""mdb_peek.py: read the structure of an MDB file. It changes nothing."""
import sys, struct, collections

FAMILY = {0: ('Jet 3', 'Access 95 and 97', 2048), 1: ('Jet 4', 'Access 2000 to 2003', 4096),
          2: ('ACE 12', 'Access 2007', 4096), 3: ('ACE 14', 'Access 2010', 4096),
          4: ('ACE 15', 'Access 2013', 4096), 5: ('ACE 16', 'Access 2016', 4096),
          6: ('ACE', 'Access 2019', 4096)}
KINDS = {0: 'empty', 1: 'data', 2: 'table definition', 3: 'index', 4: 'index leaf',
         5: 'usage map', 8: 'type 8', 9: 'type 9'}


def rc4(seed, data):
    s, j = list(range(256)), 0
    for i in range(256):
        j = (j + s[i] + seed[i % len(seed)]) & 255
        s[i], s[j] = s[j], s[i]
    out, i, j = bytearray(), 0, 0
    for c in data:
        i = (i + 1) & 255
        j = (j + s[i]) & 255
        s[i], s[j] = s[j], s[i]
        out.append(c ^ s[(s[i] + s[j]) & 255])
    return bytes(out)


def peek(path):
    b = open(path, 'rb').read()
    bad, info = [], []
    if len(b) < 4096:
        return ['the file has only %d bytes' % len(b)], info
    head = bytearray(b[:4096])
    if head[:4] != b'\x00\x01\x00\x00':
        bad.append('the file does not start with 00 01 00 00')
    name = bytes(head[4:19]).rstrip(b'\0').decode('latin1')
    if name not in ('Standard Jet DB', 'Standard ACE DB'):
        bad.append('the engine name is %r' % name)
    ver = head[0x14]
    if ver not in FAMILY:
        bad.append('version byte %d is not one we know' % ver)
        return bad, info
    eng, rel, ps = FAMILY[ver]
    n = 126 if ver == 0 else 128
    head[0x18:0x18 + n] = rc4(bytes([0xC7, 0xDA, 0x39, 0x6B]), bytes(head[0x18:0x18 + n]))
    enc = struct.unpack_from('<I', head, 0x3E)[0]
    info.append('%s (%s), %d byte pages, %d pages, %s bytes' % (eng, rel, ps, len(b) // ps, format(len(b), ',')))
    if len(b) % ps:
        bad.append('the size leaves %d bytes after the last full page' % (len(b) % ps))
    if enc:
        info.append('byte 62 is not zero, so the pages are encrypted and the page checks are skipped')
        return bad, info
    pages = len(b) // ps
    kinds = collections.Counter(b[i * ps] for i in range(1, pages))
    info.append('pages after the header: ' + ', '.join('%d %s' % (v, KINDS.get(k, 'type %d' % k)) for k, v in sorted(kinds.items())))
    if pages > 2 and b[2 * ps] != 2:
        bad.append('page 2 is not a table definition page (its type is %d)' % b[2 * ps])
    for i in range(1, pages):
        pg = b[i * ps:(i + 1) * ps]
        if pg[0] not in KINDS:
            bad.append('page %d has type %d, which none of our 85 intact files has' % (i, pg[0]))
        elif pg[0] == 0 and any(pg):
            bad.append('page %d is marked empty but has data' % i)
        elif pg[0] and pg[1] != 1:
            bad.append('page %d has %d as its second byte, and the pages of our 85 intact files have 1' % (i, pg[1]))
    return bad, info


if __name__ == '__main__':
    for path in sys.argv[1:]:
        bad, info = peek(path)
        print(path + ': ' + (info[0] if info else 'not an MDB file'))
        for line in info[1:] + (bad[:5] or ['no problem found']):
            print('  ' + line)
        if len(bad) > 5:
            print('  ... and %d more' % (len(bad) - 5))

On our sample MDB file it reads 59 pages and reports no problem. It read all 43 public MDB files in under a tenth of a second and flagged none of them. It also flagged none of the 42 ACCDB files.

The script on our sample and on two damaged copies
$ python3 mdb_peek.py sample.mdb
sample.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 59 pages, 241,664 bytes
  pages after the header: 28 data, 10 table definition, 1 index, 18 index leaf, 1 type 8
  no problem found

$ file k2.mdb
k2.mdb: data
$ mdb-count k2.mdb Table1
512
$ python3 mdb_peek.py k2.mdb
k2.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 59 pages, 241,664 bytes
  pages after the header: 28 data, 10 table definition, 1 index, 18 index leaf, 1 type 8
  the engine name is 'Xtandard Jet DB'

$ mdb-tables -1 k3.mdb; echo "exit code $?"
Unknown Jet version: 7f
Couldn't open database.
exit code 1
$ python3 mdb_peek.py k3.mdb
k3.mdb: not an MDB file
  version byte 127 is not one we know

The copy with Xtandard Jet DB shows a trap. The file command says data and the script names the broken engine name, but mdb-count still prints 512 and the rows read fine. A tool that refuses a file is not always right, and a tool that accepts one is not always right either.

The script on a copy cut inside a page and on a copy with a junk page
$ mdb-count k9.mdb Table1
512
$ python3 mdb_peek.py k9.mdb
k9.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 53 pages, 219,136 bytes
  pages after the header: 23 data, 10 table definition, 1 index, 17 index leaf, 1 type 8
  the size leaves 2048 bytes after the last full page

$ python3 mdb_peek.py k15.mdb
k15.mdb: Jet 4 (Access 2000 to 2003), 4096 byte pages, 59 pages, 241,664 bytes
  pages after the header: 27 data, 10 table definition, 1 index, 18 index leaf, 1 type 8, 1 type 180
  page 26 has type 180, which none of our 85 intact files has

What the checks cannot see

Neither check flagged 56 of the 173 copies with other data. The script flagged none of the 22 silent ones, and the count script flagged 9. A page of zeros looks like an empty page, and a cut on a page edge leaves valid pages. That is why the script said no problem for the copy cut at 10 percent.

Write down the facts of your original MDB file. Keep its size, its SHA256 hash, the list of tables and the stored row count of every table. A copy that differs in any of them is a different file, even when every tool reads it.

Our two scripts never check that a name, a number or a date is right. They show whether the structure and the counts agree, and nothing more. An MDB file that passes can still fail in Microsoft Access, which we did not use.

Want the causes of an error? Go to the causes.

Is an MDB File Safe to Open and Share? Reading starts no code, and Access can ask you to enable it

An MDB file is safe to read with mdbtools, but Access can start code that the file contains. Access disables potentially unsafe code by default, so do not click Enable Content for a file you do not trust. Treat every MDB file as private data.

Reading an MDB file with mdbtools, a script or a viewer starts no code. Microsoft’s page on trusting a database says Access disables potentially unsafe code by default and shows a Message Bar with an Enable Content button. It also describes trusted locations. We scanned no file for malware, and the 43 public MDB files are test files.

What is inside an MDB file

Tables and rows Every row of every table is in the file. Our sample is small, but a large database can have names, prices and notes.
Objects and code Microsoft’s limit is 32,768 objects in a database. Queries, forms and modules are objects. Code is what Access disables by default.
Names in the lock file Microsoft says the .ldb lock file has an entry of 64 bytes for every user. 32 bytes are the computer name and 32 are the security name.
Weak passwords The Library of Congress says password protection and encryption in MDB files are not considered secure. Microsoft says user level security is no longer effective.

The lock file next to an MDB file

Microsoft’s page on lock files says Access creates the .ldb file for shared use and deletes it when the last user closes the database. It keeps the file when a user lacks the right to delete it or when the database is marked as corrupted.

The lock file is at most about 16 KB.

So a leftover .ldb file means the database was open, was marked as corrupted or was used by someone who could not delete the file. It can show the computer names of the people who used it. Look at it before you send the folder to anyone.

Before you share an MDB file

  1. Open your copy with mdbtools and list the tables. Look at what is there.
  2. Ask if the other side needs every table. Export fewer tables to CSV when you can.
  3. Leave the .ldb file out of the folder you send.
  4. Send the MDB file over a channel you trust, and send its SHA256 hash by another route.
  5. Delete your extra copies when the other side confirms the file.

Look before you send. A database can store more than you remember. Read the table list and a few rows of every table before you share the file, and remove names and notes that the other side does not need.

Why Will Your MDB File Not Open? Eight causes, and what to do about every one

MDB files fail for eight reasons. It can be another kind of file or another version. It can be encrypted or locked. The header, the catalog or a data page can be damaged. The file can also be cut short.

The table lists what we saw in our 495 damaged copies and what mdbtools said. We used one reader on Linux, so read every fix as a first step and not as a final answer.

Eight causes of MDB files that will not open
Cause Details and fix
You have a different kind of file FileInfo lists a second kind of .mdb file, an Avid Media Database, and any file can have the wrong ending. With the version byte set to 7F, mdbtools said Unknown Jet version and Couldn’t open database, and our script said not an MDB file. Fix: Read the first 24 bytes. An Access file starts with 00 01 00 00 and the text Standard Jet DB.
The file is from another version Microsoft’s page on error 3041 covers Access 2013 and 2016. It says the database is in an outdated format and names compacting as the fix. We did not test that fix. Fix: Read byte 20 with mdb-ver, then follow Microsoft’s page for the version you use.
The file is encrypted or has a password A database code that is not 0 means the pages are encrypted, says mdbtools, and our script skips its page checks then. None of our 43 MDB files is encrypted, so we did not test this. Fix: Ask the owner for the password and open the file in Access.
The header page is damaged A zeroed header, the version byte 7F and the other version byte were refused on 45 of 45 copies. Scrambling 8 bytes gave 19 same copies and 11 refused ones. A changed engine name stopped no reader. Fix: Compare the file with its source, and let the script name the wrong byte.
The file is cut short or extended A cut at 50 percent left other data on 14 of 15 copies. A cut at 10 percent gave other data on 9 and refusals on 6, and 2 of the 9 had no message. 100 junk bytes at the end changed no row, but our script flagged all 15. Fix: Compare the size and the hash with the source.
The catalog or a table definition is damaged A zeroed page 2 was refused on all 15 copies, with a message that blames the file itself. Zeroed table definitions gave other data and a message on all 15, and neither of our checks flagged them. Fix: Copy the file again from its source or from a backup.
A data page is damaged One zeroed data page gave other data on 22 of 45 copies, and 5 of the 22 gave no message. Changing 1 byte gave 5 silent copies in 45. Every mdbtools command exited with 0 on 126 of the 173 copies with other data. Fix: Compare the row counts of two tools with your original.
A lock, a right or a driver is the problem Microsoft says Access keeps the .ldb lock file when a user cannot delete it or when the database is marked as corrupted. Wikipedia says Jet was a 32 bit engine and lists a separate 64 bit ACE driver. We did not test either. Fix: Close other users, check the folder rights and match the driver to your program.

When the reader is the problem and not the MDB file

Two kinds of damage show it. A changed engine name made the file command say data, but all 15 copies printed the same rows. Scrambling 8 header bytes was refused on 11 of 30 copies and read fine on 19. Try a second tool before you call an MDB file bad.

Fix an MDB file in seven steps

  1. Copy the MDB file, write down its SHA256 hash and work on the copy.
  2. Read the first 24 bytes with xxd -l 24 mydata.mdb. They should start with 00 01 00 00 and the text Standard Jet DB.
  3. Compare the size and the hash with the source. A file that is cut on a page edge can look fine to every tool.
  4. Read the MDB file with the count script and the structure script, and note every fault they name.
  5. Read it with a second tool, like Access, and compare the row counts.
  6. If Access says the database is in an outdated format, follow Microsoft’s page for error 3041. It names compacting as the fix, and we did not test it.
  7. If the file is damaged, copy it again from its source or from a backup. We tested no repair, so none is promised here.

We did not test repairs on files from other people. An MDB file that passes our scripts can still fail in Access, and a file that fails in mdbtools can still open there. Only the program you use knows what it accepts.

What to send when you ask for help

If a forum or a support team asks about your MDB file, send these lines. They show what the file is and where the tools stopped, and they save rounds of questions. Remove names and private data first.

A message that gets an answer
Subject: MDB file will not open
File: name, size in bytes and SHA256 hash
First bytes: the output of xxd -l 24 mydata.mdb
Engine: the output of mdb-ver mydata.mdb
Count script: the output of mdb_count_check.sh
Structure script: the output of mdb_peek.py
Program: the tool you used and its version
History: where the file came from and what changed

Not an error, but a question about similar files? Go to the versus part.

How Do You Convert an MDB File? CSV, SQLite or a tool you test first

You can export every table of an MDB file to CSV with mdb-export, and build a SQLite database with mdb-schema and mdb-export. Renaming an MDB file does not convert it. We did not test conversion in Access or in the vendor viewers.

This part reports what we tested on Linux with free tools. A converter reads the MDB file and writes new files, and the original MDB file stays unchanged.

Export an MDB table to CSV

The mdb-export command prints one table as CSV, with a header line first. Our table has 512 rows, so the file has 513 lines. The last two rows have no CD_AGENTE value, and they print as an empty first field.

Export our table to a CSV file
$ mdb-export sample.mdb Table1 > Table1.csv
$ wc -l Table1.csv
513 Table1.csv
$ tail -n 2 Table1.csv
,"abc","ddd"
,"abc","efg"

Build a SQLite database from an MDB file

The mdb-schema command writes the table definitions for SQLite, and mdb-export writes the rows as INSERT statements. A short Python line loads both into a database. SQLite counted 512 rows, the same as mdb-count. The two rows with no CD_AGENTE value became NULL.

Our MDB table in SQLite
$ mdb-schema sample.mdb sqlite > schema.sql
$ mdb-export -I sqlite sample.mdb Table1 > rows.sql
$ python3 -c "import sqlite3; c = sqlite3.connect(':memory:'); c.executescript(open('schema.sql').read() + open('rows.sql').read()); print(c.execute('select count(*) from Table1').fetchone()[0])"
512

We used the same route on all 43 public MDB files. 40 converted, and the three test2 files failed on a NUL byte. A SQLite database is a good target for old data, and the SQLITE page covers the format.

Convert an MDB file in Access

Microsoft’s comparison of MDB and ACCDB covers both formats, and the Library of Congress says Access up to 2016 can still save MDB files. We did not test saving or converting in Access, so we give no steps.

Convert an MDB file with a vendor tool

The pages of SysTools Free MDB Viewer and Freeviewer MDB Viewer both say the free version previews the data and name a paid edition at $69. We tested neither, so we cannot say which formats they write.

What you cannot convert by renaming an MDB file

Renaming an MDB file to .accdb changes only the name. We renamed our sample, and the SHA256 hash stayed the same and mdb-count still printed 512. An ACCDB file has another version byte, and a rename cannot change it.

Our sample before and after the rename
$ sha256sum sample.mdb sample-renamed.accdb
f0a1534fc68273a35272193f9c0fad5a1d1ad48d3cfbd42eee32f2ac44179def  sample.mdb
f0a1534fc68273a35272193f9c0fad5a1d1ad48d3cfbd42eee32f2ac44179def  sample-renamed.accdb
$ mdb-count sample-renamed.accdb Table1
512
Conversions and how much we know
Task What we know
MDB to CSV Tested with mdb-export. It wrote 512 rows and a header line.
MDB to SQLite Tested with mdb-schema, mdb-export and Python. 512 rows matched. 40 of 43 public MDB files converted.
MDB to ACCDB in Access Not tested. Microsoft’s page compares the two formats.
MDB to another format with a viewer Not tested. The vendors list a paid edition at $69.
MDB to ACCDB by renaming Does not work. The hash did not change.

How Does an MDB File Differ From ACCDB, MDE, LDB and MDF Files? One old format, a new one, a protected copy, a lock and a server file

An MDB file is an Access database in the format of Access 2003 and older. An ACCDB file is the newer Access format, and an MDE file is a protected MDB file. An LDB file is a lock file, and an MDF file belongs to SQL Server.

People mix these types up because all of them store tables. The table sorts them by the program that writes them and by what they store.

MDB files next to similar database files
Type What it is
MDB An Access database in the format of Access 2003 and older. Jet 3 and Jet 4 write it.
ACCDB The Access format since Access 2007. Our guide to ACCDB files covers it.
MDE and ACCDE Wikipedia calls MDE the protected version of an MDB file before Access 2007. ACCDE is the protected ACCDB file and needs Access 2007 or later.
LDB The lock file that Access creates next to a shared database. Microsoft says it has an entry of 64 bytes for every user.
MDF A SQL Server data file. Our guide to MDF files covers it.
SQLITE A SQLite database in one file. Our guide to SQLITE files covers it.
DBF A table in the dBASE format, with one table to a file. Our guide to DBF files covers it.

An MDB file can have many tables and a DBF file has one. A viewer for one type does not read the other, so check the version byte before you install a tool.

What Is the MDB File Format Made Of? The facts we could check, and where they came from

An MDB file is a Jet database in fixed size pages, and Microsoft has published no specification. The facts below come from Microsoft, Wikipedia, PRONOM, the Library of Congress, mdbtools and our checks of 43 public MDB files and 495 copies.

Facts about the MDB file format
Part What we checked
Name MDB is the Access database format of Access 2003 and earlier. Jet 3 and Jet 4 write it. (Wikipedia)
Specification Microsoft has published none. The descriptions that exist come from reverse engineering. (Library of Congress)
Signature The bytes 00 01 00 00, then Standard Jet DB and a zero byte. PRONOM lists 24 bytes for Access 2002 and a header with version 0 for Access 95. All 43 of our MDB files start that way. (PRONOM, our MDB files)
Version byte Byte 20. It is 0 for Jet 3 and 1 for Jet 4. Our ACCDB files have 2, 3 or 6. (mdbtools, our files)
Page size 2,048 bytes in Jet 3 and 4,096 bytes in Jet 4. (Wikipedia, our MDB files)
Header mask From byte 24, 128 bytes are scrambled with RC4 and the bytes C7 DA 39 6B. Jet 3 uses 126 bytes. (mdbtools)
Catalog The table MSysObjects, defined on page 2. Our sample has 21 entries. (mdbtools, our MDB file)
Page types 1 is data, 2 is a table definition, 3 is an index and 4 is an index leaf. (mdbtools, our MDB files)
Text Jet 4 added Unicode text. Our MDB files use code page 1252, and one uses 1254. (Wikipedia, our MDB files)
Limits 2 GB minus system objects, 255 users, 32,768 objects, 255 fields and 32 indexes in a table. (Microsoft)
Lock file The .ldb file has 64 bytes for every user, with the computer name and the security name. It is at most about 16 KB. (Microsoft)
Security Password protection and encryption are not considered secure. User level security is no longer effective. (Library of Congress, Microsoft)
Protected copies MDE is the protected MDB file, and ACCDE is the protected ACCDB file. (Wikipedia)
Our counts 43 public MDB files, 495 damaged copies, one reader, a row count check and a 75 line script.

About the values we list

Rules about the format come from Microsoft’s list of Access limits, Wikipedia’s Jet article and the Library of Congress record. Details of the pages come from the source of mdbtools. Counts come from our own files. Where the documents disagree or say nothing, we say so.

What we left out

We damaged 15 small and large files, and every test changed one thing. Files with years of forms, macros and attachments can react in other ways. We did not damage an ACCDB file, and we did not test an encrypted file.

We did not use Microsoft Access, Compact and Repair or the two viewers. We used mdbtools 1.0.0 only. Other versions of mdbtools can print other messages. We compared printed rows and not every byte.

The public MDB files come from a test folder and not from a business. We left out replication, user level security and the lock file contents, because we had no file to read them from.

Sources checked

For the format, see Microsoft’s page on file formats, PRONOM’s Access 2002 record and PRONOM’s record for Access 95. For the engines, see Wikipedia’s Microsoft Access article and Wikipedia’s article on ACE.

For errors and locks, see Microsoft’s page on error 3041 and Microsoft’s article on lock files. For the .mdb ending, see the FileInfo entry. Every count came from files and scripts in our research folder.

Frequently Asked Questions About MDB Files

What is an MDB file?

An MDB file is a Microsoft Access database in the format of Access 2003 and older. It stores tables and rows in one binary file made of fixed size pages. Access 2007 and later write the newer ACCDB file by default.

How do I open an MDB file?

Open it in Microsoft Access, or read it with a free tool like mdbtools. Viewers from SysTools and Freeviewer read it on Windows without Access. We tested mdbtools only, and the rest comes from Microsoft and the vendor pages.

How do I open an MDB file without Access?

Use mdbtools on Linux, or a viewer from SysTools or Freeviewer on Windows. mdbtools prints the tables as CSV, and it changes nothing in the file. The free versions of both viewers only preview the data, says their pages.

Is an MDB file a virus?

No. An MDB file is a database, and reading it with mdbtools starts no code. Access can start code that a database contains, so it disables potentially unsafe code by default and shows a Message Bar. Do not click Enable Content for a file you do not trust.

What is the difference between MDB and ACCDB?

MDB is the format of Access 2003 and older, and ACCDB is the format since Access 2007. Microsoft says ACCDB adds multivalued fields, attachments, stronger encryption and more. The version byte differs too. It is 0 or 1 in our MDB files, and 2 or higher in ACCDB files.

Can I convert an MDB file to ACCDB, CSV or SQLite?

Yes, but not by renaming it. With free tools, mdb-export writes a table as CSV. The mdb-schema command with mdb-export builds a SQLite database. We did not test conversion in Access or in the viewers.

How do I check an MDB file?

Hash the file, read its first 24 bytes and name its engine with mdb-ver. Then compare the stored row count of every table with the rows that mdb-export prints, and use our 75 line script. Together they flagged 117 of the 173 damaged copies that printed other data.

Why does my MDB file show fewer rows than I expect?

A damaged page can hide rows without a word. In our test 148 of 173 copies with other data printed fewer rows, and the median loss was 17.3 percent. Compare the row count with your original, and read the file with a second tool.

Does the file command prove that an MDB file is good?

No. It named all 173 of our damaged copies that printed other data a Microsoft Access Database. It looks at the first bytes only, so a damaged page deeper in the file does not change its answer.

Does an MDB file have a signature?

Yes. The first four bytes are 00 01 00 00, and the text Standard Jet DB follows. All 43 of our public MDB files start that way, and PRONOM lists the same bytes for Access 2002. A start that differs is a warning sign.

Can I rename an MDB file to ACCDB?

No. A rename changes the name of an MDB file and nothing else. We renamed our sample, and its SHA256 hash stayed the same. The version byte inside the file does not change, so the file is still an MDB file.

How big can an MDB file be?

Microsoft lists a limit of 2 GB minus the space of system objects for .accdb and .mdb files. A database can have up to 255 users at once and 32,768 objects. Our biggest public MDB file is 10,514,432 bytes.

Still Stuck With an MDB File? Two routes out, and where to look next

Your MDB file won’t open

Read the first 24 bytes and follow the seven steps. The cause table lists what to try in order.

You do not know what it contains

Look at how an MDB file is built, and then start our script.

Is it the newer Access format? An ACCDB file is the Access format since 2007. Our page on ACCDB files covers it, and the versus part shows how the two differ.

Is it a SQL Server file? An MDF file is a SQL Server data file, and an LDF file is its log. Our page on MDF files and our page on LDF files cover them.

Is it a small database in one file? A SQLite database is one file, and a DBF file is one table. Our page on SQLITE files and our page on DBF files cover them.

Is the data unknown? Our page on DAT files covers files with no clear type, and the file extension resource library lists many more.

Is your type missing? Send it on the submit a file type page.