
Funding: CypherpunkGuide may earn referral fees through linked buying guides. This article contains no direct affiliate purchase links. No wallet vendor sponsored this work.
The application that coordinates signing is gone. One signing device has failed. Two seed backups—the information used to regenerate signing keys—remain. That sounds like exactly the failure a 2-of-3 arrangement was designed to survive.
It may be. The number describes a signature requirement, not a complete recovery procedure. The missing question is whether you can reconstruct the wallet those keys were signing for.
This article concerns conventional Bitcoin P2WSH (pay-to-witness-script-hash) wallets using sortedmulti. Their script defines the spending conditions: a required number of signatures from a specified set of public keys. It does not evaluate hardware devices, Taproot signing schemes, or recovery compatibility between wallet products. If you are still establishing ordinary self-custody, start with the receipt, signing, and recovery checks.
Two signatures and a complete wallet description#
Two signing keys can satisfy a 2-of-3 script, but reconstructing its addresses requires the full script configuration. That includes all three public keys at the relevant derivation points, the threshold, and the script type. Three keys do not necessarily mean three different people.
A descriptor is a structured description of the scripts a wallet should recognize. It can specify extended public keys, which derive families of public keys, and the paths used to derive them. BIP380 explains why private-key backups alone can leave script types and derivation paths uncertain. BIP383 defines the multisig descriptor expressions, including sorting the derived public keys in sortedmulti.
These are three different things to inventory:
| Material | What it contributes | What it does not establish by itself |
|---|---|---|
| Signing backups | The private keys needed for authorization, when restored correctly | Which full multisig configuration held the funds |
| Wallet configuration | The threshold, all cosigners’ public keys, script type, and derivation information | Possession of enough private keys to sign |
| Discovery conditions | Which branches and address ranges to search, and relevant historical data | A completed, valid signature |
Software may preserve several of these in one wallet file. A descriptor may preserve much of the configuration. The important question is what the export actually contains and whether the recovery software understands it. A filename or a checksum does not answer that question.
Sparrow’s backup-dialog implementation explicitly mentions the required seeds and all extended public keys, with a wallet file or descriptor as configuration backups. That is a source-code observation, not a hands-on assessment of its current interface or another product’s import compatibility.
What the isolated recovery experiment showed#
On 24 September 2026, we used Bitcoin Core 31.1 in regtest, an isolated test-chain mode, to check address reconstruction, discovery of a specified test output, signature completion, and acceptance by the local node separately. An output is a unit of funds created by a transaction. The measured experiment interval was 13.3 seconds, excluding initial version/hash checks and final shutdown/cleanup. It used public dummy inputs and no real funds, and ended with peer networking disabled and zero connections.
Each of the first five cases reconstructed the configuration in a separate, newly created watch-only wallet. The matching test output was 0.01000000 regtest BTC. Keys A, B, and C were derived from publicly specified dummy inputs; this was not seed entry on a physical device.
| Material supplied | Same receive addresses? | Specified test output found? | Signature complete? | Local node acceptance test |
|---|---|---|---|---|
| Complete configuration + A/B | Yes | Yes | Yes | Accepted |
| Complete configuration + A/C | Yes | Yes | Yes | Accepted |
| Complete configuration + B/C | Yes | Yes | Yes | Accepted |
| Complete configuration + A only | Yes | Yes | No | Rejected |
| Public configuration only | Yes | Yes | No | Rejected |
| Substitute 2-of-2 policy without C | No | No balance found | Not tested | Not tested |
| Wrong script wrapper | No | No balance found | Not tested | Not tested |
| Wrong derivation branch | No | No balance found | Not tested | Not tested |
For the last three rows, we compared the funded receive address at index 1 and found no wallet balance in the imported range. This does not establish anything about addresses outside that range. The missing-third-key case does not attempt every possible recovery technique: replacing 2-of-3 with 2-of-2 tests a wrong reconstruction, not whether another backup or historical script can help.
We then submitted the A/B transaction to the private test chain. The wallet with both branches found its 0.00599000 regtest BTC change output. The receive-only wallet, which had found the original test payment, did not find that change output. This was an output-specific comparison, not a claim that the receive-only wallet’s total balance became zero; separate mining outputs existed in the experiment. A deliberately damaged descriptor checksum was also rejected, with successful checks of the original descriptor immediately before and after it.
The script, measured results, safety regression tests, and empty recovery inventory accompany the article. The imported address range was 0–2, with a rescan timestamp of 0. Signature tests used derived dummy private keys and correct script/previous-output data supplied from the complete reference wallet. They do not demonstrate a complete seed-restoration procedure, hardware-wallet recovery, or cross-product compatibility. Local acceptance testing does not broadcast a transaction. This controlled run does not estimate real-world recovery success rates.
Reproduction requirements and the command are in the lab notes. Do not use any of these public test keys for real funds.
Finding funds and spending funds are separate checks#
A restored wallet can recognize an output without being able to spend it. Conversely, a wallet can show no matching balance because its search conditions are incomplete.
Receiving addresses and change addresses commonly use different derivation branches. If the restored description omits the scripts used for change, a payment can move the remaining funds outside the set that wallet recognizes. The internal classification flag is not itself the same thing as including or excluding a branch.
Core’s descriptor-import implementation and help distinguish the import timestamp, address range, and internal classification. Synchronization and available historical blocks can also matter. A zero display is a finding to investigate, not evidence by itself that the coins are gone.
This is also why an import-success message or a field called “solvable” is insufficient. The relevant proof of signing is a completed transaction that satisfies the script. A local regtest establishes behavior in that controlled test; it is not a mainnet confirmation or a device-compatibility test.
Public configuration still deserves privacy protection#
A public-only descriptor cannot sign by itself, but it can expose the addresses derivable from the public keys and paths it contains. Sharing it may allow someone to associate balances and transactions across that scope.
Do not treat “public key” as an instruction to publish your wallet configuration. Keep its audience limited, and distinguish it from a private descriptor, which can contain private keys. There is a further reason not to promise that public-key disclosure is always harmless to funds: BIP32 describes how a parent extended public key combined with a non-hardened child private key can expose the parent private key.
That combined-disclosure case is different from a public descriptor alone. Neither statement makes posting wallet data to a recovery forum a good diagnostic step. The broader transaction-linking problem is covered in our Bitcoin on-chain privacy guide.
Check the recovery plan without collecting secrets#
A useful inventory records whether the necessary material exists and has been checked. It should not become a new, casually shared collection of secrets.
The attached inventory asks about the signing threshold, configuration backup, receiving and change coverage, supported import format, and separate discovery/signing checks. It has no fields for seed words, passphrases, public keys, or actual descriptors. Record status, not values.
Use your wallet or signing-device provider’s documented recovery-check process. Do not enter real seeds into a website, chat, or this experimental script. Our publicly reproducible dummy keys are unsuitable for real funds. A general encrypted-backup restore test can establish that stored files are recoverable; it cannot establish that their contents are sufficient to spend from a particular Bitcoin wallet.
Multisig adds things to preserve, coordinate, and test. If those responsibilities are not manageable, adding signing devices does not automatically improve your recovery plan. This article is a way to inspect that complexity, not a recommendation to buy more devices.
Key takeaways#
Questions that remain during recovery#
Does losing the descriptor make recovery impossible?#
Not necessarily. Another compatible wallet backup may contain the configuration. A known script may preserve some information: for example, spending a P2WSH output reveals its witness script under BIP141. That does not automatically reveal every extended public key or reconstruct the wallet’s entire address space. Recovery depends on which material remains.
Does a valid checksum prove I have the right configuration?#
No. A checksum helps detect transcription errors in a descriptor. Someone can produce a different valid descriptor with its own valid checksum. Match configuration against a trusted backup and the wallet you intended to recover; do not equate syntax validity with authenticity.
Sources and saved copies#
Original sources support the claims above. Saved copies preserve the cited material.
| Source | Original URL | Archived |
|---|---|---|
| BIP380 | Original URL | Archived |
| BIP383 | Original URL | Archived |
| Sparrow — MultisigBackupDialog.java | Original URL | Archived |
| Bitcoin Core 31.1 — backup.cpp | Original URL | Archived |
| BIP32 | Original URL | Archived |
| BIP141 | Original URL | Archived |


