Error message
Address does not refer to key
Also printed as
- error code: -3 error message: Address does not refer to key
`bitcoin-cli` prints "error code: -3" and "error message:" on the lines before the text. JSON-RPC clients see `{"code": -3, "message": "Address does not refer to key"}`.
Bitcoin Core RPC — verifymessage / signmessage with a non-P2PKH address
What it means
Bitcoin Core's message signing (`signmessage`/`verifymessage`) implements the original "Bitcoin Signed Message" scheme, which only works for legacy P2PKH addresses: the signature recovers a public key, and Core compares its hash with the address. Native SegWit (`bc1q…`), Taproot (`bc1p…`) and P2SH (`3…`) addresses are not "key" addresses in that sense, so Core rejects them with RPC error -3 instead of returning true or false.
Why it happens
A native SegWit address
commonMost wallets now default to `bc1q…` addresses. Exchanges and proof-of-reserves flows that ask for a signed message from such an address cannot use Core's legacy scheme.
Taproot or P2SH address
occasional`bc1p…` and `3…` (wrapped SegWit, multisig) addresses have no single public key hash Core could compare against.
A signature made by another wallet for a SegWit address
occasionalElectrum, Trezor and others extend the legacy format for SegWit (BIP-137 header bytes 35–42) or use BIP-322. Core's `verifymessage` accepts neither.
How to fix it
- 1.
Sign with a legacy address in Core
If the counterparty only needs proof of control over a key in your wallet, create a legacy address for the proof.
bash # Bitcoin Core signs and verifies messages only for legacy P2PKH addresses (1... / m... / n...) addr=$(bitcoin-cli getnewaddress "proof" legacy) sig=$(bitcoin-cli signmessage "$addr" "I own this address") bitcoin-cli verifymessage "$addr" "$sig" "I own this address" - 2.
Use BIP-322 for SegWit and Taproot
BIP-322 defines message signatures for every address type. Use a library or wallet that implements it, and agree on it with the verifier.
js // SegWit / Taproot addresses: BIP-322 "simple" signatures, e.g. with the bip322-js library import { Verifier } from "bip322-js"; const ok = Verifier.verifySignature("bc1q...", "I own this address", signatureBase64);