Error: stack underflow — OP_ADD requires 2 items
7. Common Script Execution Errors
OP_RETURN in Execution Path
OP_RETURN immediately marks the script as invalid when encountered in the execution path. This is different from OP_RETURN appearing in an OP_IF/OP_ENDIF branch that is not taken. Any script that reaches OP_RETURN during active execution fails.
Error: Script failed — OP_RETURN encountered
Stack Underflow
Every opcode that pops items requires a sufficient stack depth. If you call
OP_ADDwith fewer than 2 items on the stack, execution fails:btcdeb '[OP_1 OP_ADD]' # Error: stack underflow — OP_ADD requires 2 itemsMitigation: carefully count push and pop operations before each consuming opcode.
OP_EQUALVERIFY Failure
If the two top stack items are not equal,
OP_EQUALVERIFYcauses an immediate failure. The most common cause in P2PKH is providing a public key whose hash does not match the hash embedded in the scriptPubKey:Error: Script failed — OP_EQUALVERIFY: stack top items not equal
Debug steps:
Verify you are hashing the correct (compressed vs. uncompressed) public key.
Confirm the hash in the scriptPubKey matches your key format.
Use
btcdebto inspect the stack at step 4 of P2PKH execution.OP_CHECKSIG Failure
OP_CHECKSIGreturns0(false) rather than causing an immediate error, but a0result will ultimately cause the script to fail. Common causes:
Signature covers wrong data: The signature must commit to the correct serialization of the transaction (sighash preimage). Any mismatch in inputs, outputs, or sighash type causes failure.
Wrong sighash type: The sighash byte appended to the signature must match what was signed.
Non-canonical DER encoding: Pre-BIP66, non-canonical DER signatures were accepted. Post-BIP66, they are rejected.
Compressed vs. uncompressed key mismatch: In P2PKH, the key in the scriptSig must be in the same format (compressed/uncompressed) that was used when deriving the address.
# Check if a signature is low-S (BIP62 compliant) from ecdsa.numbertheory import inverse_mod def is_low_s(signature_hex: str, order: int) -> bool: sig = bytes.fromhex(signature_hex) # Parse S from DER: skip 30 <len> 02 <r_len> <R bytes> 02 <s_len> r_len = sig[3] s_len = sig[5 + r_len] s_start = 6 + r_len S = int.from_bytes(sig[s_start:s_start+s_len], 'big') return S <= order // 2OP_CHECKMULTISIG Off-by-One Bug
Due to a historical bug,
OP_CHECKMULTISIGpops one extra item off the stack (beyond the signatures and keys). This is why all P2SH multisig scriptSigs begin withOP_0. Forgetting this causes a stack underflow.Non-Minimal Push Encoding (BIP62/BIP141)
SegWit introduced stricter rules requiring minimal push encoding. For example:
Pushing an empty byte array must use
OP_0, notOP_PUSHDATA1 0x00.Pushing a 1-byte value
0x01–0x10must useOP_1–OP_16, not a 1-byte data push.Violating these rules in SegWit scripts causes validation failure even if the logic is correct:
Error: mandatory-script-verify-flag-failed (Data push larger than necessary)
Pro Tip
When debugging scripts, always start with a high-level disassembly before diving into the stack trace. Tools like
bitcoin-cli decodescriptare your first line of defense in identifying standard script patterns.
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: