wallet.dat is the file Bitcoin Core keeps your keys in. Almost everything else people believe about it is either out of date or was never true. This is a reference page: what the file is, how to identify which of two very different formats you are holding, where it lives, and what each record inside it means. If you want the repair procedures instead, they are in how to recover a corrupt or deleted wallet.dat, and the service page is Bitcoin Core wallet recovery.
What is a wallet.dat file?
Locked out of a wallet like this one?
I repair hardware wallets, crack forgotten passwords, and rebuild broken seed phrases — on my own bench in Denver.
A wallet.dat file is the private database Bitcoin Core uses to store the private keys, addresses, key metadata, and transaction records belonging to one wallet. It is not a text file, it is not human readable, and it does not contain your balance. Your balance lives on the blockchain. wallet.dat holds the keys that prove the coins are yours, which is why a copy of the file is a copy of the money and why it is the only thing in your Bitcoin directory that genuinely cannot be regenerated.
One name covers two completely unrelated file formats. Bitcoin Core's own documentation states it plainly: wallet.dat is "a BDB database in older wallets or a SQLite database in newer ones" (doc/files.md). Nearly every confusing error people bring us starts here, because a tool written for one format gives a meaningless message when handed the other.
Which format do I have? Check the first bytes
You do not need to open the file to answer this. Both formats announce themselves in their opening bytes, and neither check requires a password.
| Format | Era | Signature | Where |
|---|---|---|---|
| Berkeley DB (legacy) | Bitcoin 0.1 through the last legacy-capable release | Btree magic 0x00053162 |
4 bytes at offset 12 |
| SQLite (descriptor) | Bitcoin Core 0.21 and later | ASCII SQLite format 3\0 |
first 16 bytes |
For the Berkeley DB case, the magic number is DB_BTREEMAGIC, defined as 0x053162 in the Berkeley DB headers, and the metadata page puts the 4-byte magic field at offset 12, after an 8-byte LSN and a 4-byte page number. It is stored in the machine's native byte order, so on a normal x86 machine you will see the bytes 62 31 05 00 rather than the value written left to right. A file whose offset-12 magic is 0x00061561 is a Berkeley DB hash database, not a btree, and is not a Bitcoin Core wallet.
For the SQLite case there is a second, stronger check. Bitcoin Core writes the network's magic bytes into SQLite's application_id header field, a big-endian 32-bit value at offset 0x44, and refuses to load a wallet whose id does not match the network it is running (src/wallet/sqlite.cpp). For mainnet that value is 0xf9beb4d9. A SQLite file that lacks it is some other program's database that happens to be called wallet.dat.
If you would rather not count bytes in a hex editor, our free Wallet File Inspector does exactly these checks. It runs entirely in your browser, nothing is uploaded, and it never asks for a password.
Where Bitcoin Core keeps wallet.dat
The defaults, from Bitcoin Core's own file documentation:
| OS | Default data directory |
|---|---|
| Windows | %LOCALAPPDATA%\Bitcoin\ |
| macOS | $HOME/Library/Application Support/Bitcoin/ |
| Linux | $HOME/.bitcoin/ |
Two wrinkles account for most "there is no wallet.dat" searches.
The Windows path moved. Bitcoin Core 28.0 changed the Windows default from C:\Users\<name>\AppData\Roaming\Bitcoin to C:\Users\<name>\AppData\Local\Bitcoin, and noted that Core "will check the existence of the old directory first and continue to use that directory for backwards compatibility if it is present" (release notes 28.0). If you are hunting for a wallet from an older install, look in Roaming first. AppData is hidden by default in Explorer, which is why so many people conclude the file is gone.
Wallets moved into a subdirectory. A named wallet lives in wallets/<wallet_name>/. The default unnamed wallet lives in wallets/, and if that folder does not exist, in the data directory itself. So on an old install you may find wallet.dat sitting loose at the top level, and on a newer one you will find several of them, each in its own folder, all with the same filename.
Three sibling files show up next to a legacy wallet and are worth recognising:
database/is the Berkeley DB environment. Core creates it at start and deletes it on shutdown, and its documentation says to treat it with the same care aswallet.datitself. If the node died without shutting down cleanly, this folder is still there and holds the unflushed tail of your recent writes. Copy it along with the wallet.db.logis the Berkeley DB error file. It is often the only readable record of what went wrong..walletlockis the Berkeley DB lock file.
Before you do anything else with a file you care about, copy it somewhere else and work on the copy. That advice is not decoration. It is the difference between a recoverable case and an unrecoverable one, and it is the first step in the corrupt or deleted wallet.dat guide.
What is inside a legacy wallet.dat
A legacy wallet.dat is a Berkeley DB btree whose keys are serialized pairs of a short type string and, usually, an identifier. Those type strings are declared in one place in Bitcoin Core, the DBKeys namespace in src/wallet/walletdb.cpp, and they are what any recovery tool is really looking for when it walks the file.
The ones that matter for recovery:
| Record | Meaning |
|---|---|
key |
An unencrypted private key, stored against its public key |
ckey |
An encrypted private key. The presence of ckey records is what tells you the wallet is passphrase protected |
mkey |
The encrypted master key, plus the salt and derivation parameters used to unwrap it |
keymeta |
Key metadata, including creation time and, on HD wallets, the derivation path |
hdchain |
The HD chain state: which seed is in use and how far the chain has been derived |
pool |
Keypool entries, pre-generated keys not yet handed out as addresses |
name |
The address book label attached to an address |
purpose |
Whether an address book entry is a receiving address or a send-to contact |
cscript |
A redeem script, for pay-to-script-hash addresses |
tx |
A wallet transaction record |
defaultkey |
The wallet's default address, in very old wallets |
version / minversion |
The wallet format version, and the minimum version required to read it |
bestblock |
The last block the wallet was scanned against |
watchs / watchmeta |
Watch-only scripts and their metadata |
wkey |
An obsolete key record from the earliest wallets, kept for reading old files |
walletdescriptor and its key, ckey and cache variants |
Descriptor records, in a descriptor wallet |
Two practical consequences follow from this list.
A pre-HD wallet, which is anything created before Bitcoin Core 0.13, has no seed phrase at all. Its keys were generated independently and there is nothing to write on a card. That is not a mistake anyone made; it is how the software worked. If someone has told you every Bitcoin wallet has twelve words behind it, that is the reason yours does not.
The keypool is why a restored wallet can show a balance that is too low. Old Core versions pre-generated a limited number of keys, and if you used more addresses than the backup's keypool covered, an old wallet.dat can be missing keys for change that came back to you later. That specific failure has its own write-up in Bitcoin Core restored but no balance.
How the passphrase is stored
If you encrypted your wallet, Bitcoin Core did not encrypt each key with your passphrase. It generated a random master key, encrypted every private key with that, and then encrypted the master key with a key derived from your passphrase. That wrapped master key is the mkey record, and it is the only thing a password search actually has to attack.
From src/wallet/crypter.h:
- The cipher is AES-256-CBC, for both the master key and the private keys.
- The key is 32 bytes, the salt is 8 bytes.
- Derivation method
0means OpenSSL'sEVP_BytesToKeywith SHA-512. Method1is scrypt. nDeriveIterationsdefaults to 25,000, with a source comment explaining that 25,000 rounds was "just under 0.1 seconds on a 1.86 GHz Pentium M".
That last number is the whole story of why old Bitcoin Core passphrases are attackable at all. Twenty-five thousand SHA-512 rounds was a sensible cost in 2011 and is a trivial one now, so the search rate against a wallet.dat is high compared with a modern password format. The iteration count is stored in the file, so a wallet encrypted on a faster machine may carry a higher one and search proportionally slower. What actually decides a case is how much you remember about the passphrase, not the hardware; that reasoning is worked through in how I recover a forgotten wallet.dat password.
This is also why tools ask you for mkey and ckey. They are not asking for anything secret in plaintext. They are extracting the wrapped master key and its parameters so the search can run offline against a hash rather than against the wallet.
What a descriptor wallet.dat holds instead
Bitcoin Core 0.21 introduced descriptor wallets, which store the same secrets in a SQLite database rather than a Berkeley DB one. The release notes give the reason directly: Berkeley DB 4.8 is old, is not actively maintained, was never meant to be an application database, and is prone to file corruption (release notes 0.21.0).
The file is still called wallet.dat. It still lives in wallets/<name>/. It still cannot be opened without the passphrase. But it is a different container holding output script descriptors, and the great majority of the wallet.dat tooling you will find in a search engine or in an old forum thread predates it entirely and will fail on it, sometimes silently. If a well-regarded tool told you your file is "not a wallet", check the first sixteen bytes before you believe it.
Bitcoin Core 30 will not open a legacy wallet.dat
This is the single most important current fact about the format, and it catches people who have not touched their node in years.
In Bitcoin Core 30.0, "BDB legacy wallets can no longer be created or loaded. They can be migrated to the new descriptor wallet format" (release notes 30.0). The migration path is the migratewallet RPC. A set of legacy-only RPCs went with it, including dumpprivkey, dumpwallet, importprivkey, importwallet, importmulti, addmultisigaddress, sethdseed and upgradewallet, which is worth knowing because a great many step-by-step recovery walkthroughs online are built on exactly those commands.
And there is a migration bug you need to know about. Bitcoin Core published an advisory on 2026-01-05 covering versions 30.0 and 30.1: when the migration of a wallet.dat fails, "all files in the wallet directory may be deleted in the process, potentially resulting in a loss of funds." The trigger requires "the presence of a default (unnamed) wallet.dat file, which has not been created by default since 0.21", that then fails to be migrated or loaded. One route in is pruning being enabled while the wallet was unloaded. Binaries for the affected releases were pulled from bitcoincore.org, and the fix landed in 30.2 (Bitcoin Core advisory).
Read the trigger condition again, because it describes an old wallet precisely. A default unnamed wallet.dat from before 0.21 that does not migrate cleanly is exactly the file a person digging out a decade-old backup is holding. If that is you: work on a copy, keep the original offline and untouched, and do not point a 30.0 or 30.1 node at it.
What wallet.dat is not
It is not a downloadable balance. A steady share of the searches that reach this site are for "wallet.dat with balance" and "free wallet.dat download". Those files are bait. The realistic outcomes are a file that is encrypted with a passphrase you will never have, a file with no spendable coins in it, malware in the download, or a setup where any coins you do move are swept away instantly by a script watching the address. There is no honest version of this. If you are looking for one because you are trying to recover your own money, the pages above are the real path, and the how to spot a fake recovery service checklist covers what happens to people who go looking in that part of the internet.
It is not a seed phrase. No amount of work on a pre-HD wallet.dat produces twelve words, because those words were never generated.
It is not recoverable by pattern matching alone. A wallet.dat carved off a dead drive is often a fragment, and a fragment can still be worth a lot or worth nothing depending on which pages survived. The deleted-file case has its own reference in does PhotoRec recover a wallet.dat.
It is not something to hand to a stranger. A copy of the file is a copy of the coins. Nobody legitimate needs your unencrypted wallet to give you a quote, and nobody legitimate contacts you first. That commitment, and what to check before you trust anyone with a wallet file, is on the scam warning page.
If you are stuck
The file is more durable than most people expect. A wallet.dat written in 2012 still holds spendable keys in 2026, and the fact that current software refuses to open it is a tooling problem, not a lost-coins problem. What it needs is the right format identified, the right era of tooling, and a copy that nobody has written over.
If you would rather not do that yourself, Bitcoin Core wallet recovery is what we do most, and the wallet and key recovery tools survey lists the software worth trying first if you would rather do it yourself.
Sources
- Bitcoin Core
doc/files.mdon the default data directory per OS, thewallets/layout,wallet.datbeing "a BDB database in older wallets or a SQLite database in newer ones", and thedatabase/,db.logand.walletlocksiblings: https://github.com/bitcoin/bitcoin/blob/v29.0/doc/files.md (retrieved 2026-09-08) - Bitcoin Core
src/wallet/walletdb.cpp, theDBKeysnamespace, for the record type strings listed above: https://github.com/bitcoin/bitcoin/blob/v29.0/src/wallet/walletdb.cpp (retrieved 2026-09-08) - Bitcoin Core
src/wallet/crypter.hon AES-256-CBC, the 32-byte key and 8-byte salt, derivation method 0 beingEVP_sha512, and the default 25,000 iterations with its Pentium M comment: https://github.com/bitcoin/bitcoin/blob/v29.0/src/wallet/crypter.h (retrieved 2026-09-08) - Bitcoin Core
src/wallet/sqlite.cppon the SQLiteapplication_idbeing set to, and checked against, the network magic: https://github.com/bitcoin/bitcoin/blob/v29.0/src/wallet/sqlite.cpp (retrieved 2026-09-08) - Bitcoin Core
src/kernel/chainparams.cppfor the mainnet message start bytesf9 be b4 d9: https://github.com/bitcoin/bitcoin/blob/v29.0/src/kernel/chainparams.cpp (retrieved 2026-09-08) - Bitcoin Core 0.21.0 release notes on descriptor wallets using SQLite, and why Berkeley DB 4.8 was replaced: https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-0.21.0.md (retrieved 2026-09-08)
- Bitcoin Core 28.0 release notes on the Windows data directory moving to
AppData\Localand the backwards-compatible check for the old path: https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-28.0.md (retrieved 2026-09-08) - Bitcoin Core 30.0 release notes on BDB legacy wallets no longer being created or loaded,
migratewallet, and the removed legacy-only RPCs: https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-30.0.md (retrieved 2026-09-08) - Bitcoin Core advisory "Wallet Migration Failure May Delete Unrelated Wallet Files In Bitcoin Core 30.0 and 30.1", for the quoted trigger condition, the deletion behaviour, and the 30.2 fix: https://bitcoincore.org/en/2026/01/05/wallet-migration-bug/ (published 2026-01-05, retrieved 2026-09-08)
- Berkeley DB
src/dbinc/db.inforDB_BTREEMAGIC0x053162andDB_HASHMAGIC0x061561: https://github.com/berkeleydb/libdb/blob/master/src/dbinc/db.in (retrieved 2026-09-08) - Berkeley DB
src/dbinc/db_page.hfor theDBMETApage layout that places the 4-byte magic at offset 12: https://github.com/berkeleydb/libdb/blob/master/src/dbinc/db_page.h (retrieved 2026-09-08)
