RPC error -32003: Transaction signature verification failure
Last updated:
At a glance
| Property | Value |
|---|---|
| Code | -32003 |
| Message | Transaction signature verification failure |
| Category | transaction |
Cause
One or more required signatures are missing or invalid: a signer keypair did not sign, the wrong message was signed, or the fee payer / required signer set does not match the transaction's account metas.
Solution
- Confirm every account marked as a signer actually signed the message.
- Verify the fee payer is included and signs first.
- Re-derive and re-sign the exact serialized message (no post-sign mutation).
- Check you are signing the v0/legacy message format your client expects.
What the node checked
A Solana signature covers the exact serialized message: header, account keys, blockhash and instructions. Change one byte after signing and the signature is no longer valid for the message. The node checks every required signature against the message and answers -32003 if any fails. It does not say which one, so the search is on your side.
On the wire, preflight reports this as Transaction signature verification failure. With skipPreflight: true the transaction is dropped without a useful answer, because no validator can process it. Keep preflight on while you debug signing.
Find the failing signer
The message header says how many signatures are required, and those signers are the first entries in accountKeys, with the fee payer first. Deserialize what you are about to send, and check each signature against each key before you send it.
| Symptom | Likely cause | Check |
|---|---|---|
| Signed in a wallet, failed after | An instruction was added after signing, such as a priority fee | Add compute budget instructions before signing |
| All-zero signature | A required signer never signed | Compare numRequiredSignatures with the signers you passed |
| Works for one wallet only | The fee payer changed after signing | Set the fee payer before signing |
| Fails after refreshing the blockhash | The blockhash changed, so the old signature is invalid | Sign again after any change |
| Partial signing flow | One party rebuilt the message | Pass serialized bytes between signers, do not rebuild |
Debug it before sending
Most libraries can verify a transaction's signatures locally before it goes anywhere, and this is the quickest way to find the fault: it needs no network, and it tells you which public key failed. Run that check just before sendTransaction, on the exact bytes you are about to send. If local verification passes and the node still answers -32003, compare the bytes: something between the check and the request changed them, such as a re-encoding step or a helper that rebuilt the message.
When several parties sign, the order of operations matters. Everyone must sign the same message, so the blockhash, the fee payer and every instruction have to be final before the first signature. A backend that adds a priority fee after a wallet has signed will always fail here. Either add the compute budget instructions before the wallet sees the transaction, or have the wallet sign last. The same applies to anything that changes the blockhash: a retry that fetches a new hash has to collect every signature again, which is why a multi-party flow should resend the same bytes while they are still valid.
Not the same as a length mismatch
Agave has a separate code, -32013 Transaction signature length mismatch, for a transaction whose signature count does not match its header. That is a serialization problem rather than a wrong key. If you see -32602 instead, the transaction string could not be decoded at all: check that encoding matches what you sent (invalid params).
Example
{
"id": 1,
"error": {
"code": -32003,
"message": "Transaction signature verification failure"
},
"jsonrpc": "2.0"
}FAQ
- Why does "Transaction signature verification failure" happen?
- One or more required signatures are missing or invalid: a signer keypair did not sign, the wrong message was signed, or the fee payer / required signer set does not match the transaction's account metas.
- How do I fix "Transaction signature verification failure"?
- Confirm every account marked as a signer actually signed the message. Verify the fee payer is included and signs first. Re-derive and re-sign the exact serialized message (no post-sign mutation). Check you are signing the v0/legacy message format your client expects.
- Does -32003 mean my private key is wrong?
- Sometimes, but usually the message changed after signing, or a required signer was left out. A wrong key is one of several causes.
- Why does adding a priority fee break my signature?
- Compute budget instructions are part of the message. Add them first, then sign, or the signature no longer matches.