Error Codes

Every error the contract can return, with the likely cause and the fix.

When a contract call fails, the transaction reverts with a numeric error code like u1001. The frontend maps these to friendly messages, but when you're debugging directly you'll want the full catalog.

Where you'll see these

Error codes appear in wallet rejection dialogs, in transaction failure pages on the Hiro Explorer, and in the result field of failed chainhook events.

Authorization errors

CodeTypeDescription
u1000ERR_UNAUTHORIZEDThe caller is not allowed to perform this action. Usually means you're trying to act on someone else's invoice/subscription/merchant record.
u1001ERR_NOT_OWNEROnly the contract deployer can call this function (e.g., updating the fee rate or pausing the contract).
u1002ERR_CONTRACT_PAUSEDThe contract has been paused for maintenance. Wait for an unpause before retrying.

Merchant errors

CodeTypeDescription
u2000ERR_MERCHANT_NOT_FOUNDNo merchant is registered for the given principal. Register first with register-merchant.
u2001ERR_MERCHANT_ALREADY_REGISTEREDThis wallet is already registered as a merchant.
u2002ERR_MERCHANT_INACTIVEThe merchant has been deactivated and cannot accept new payments.
u2003ERR_MERCHANT_SUSPENDEDThe merchant has been administratively suspended.

Invoice errors

CodeTypeDescription
u3000ERR_INVOICE_NOT_FOUNDNo invoice with this ID exists.
u3001ERR_INVOICE_EXPIREDThe invoice's expires-at block has passed. Create a new invoice.
u3002ERR_INVOICE_CANCELLEDThe merchant cancelled this invoice.
u3003ERR_INVOICE_ALREADY_PAIDInvoice is fully paid. For partial invoices, this means total received = amount.
u3004ERR_AMOUNT_TOO_LOWPayment amount is less than the minimum, or you're trying to pay less than full on an invoice that doesn't allow partial payments.
u3005ERR_AMOUNT_TOO_HIGHPayment amount exceeds the invoice amount and allow-overpay is false.
u3006ERR_INVOICE_NOT_PAYABLEInvoice is in a status (cancelled, expired, refunded) that doesn't accept payments.
u3007ERR_INVOICE_LOCKEDInvoice has received at least one payment and can no longer be updated — only refunded.

Subscription errors

CodeTypeDescription
u4000ERR_SUBSCRIPTION_NOT_FOUNDNo subscription with this ID exists.
u4001ERR_SUBSCRIPTION_CANCELLEDSubscription is cancelled. Create a new one to resubscribe.
u4002ERR_NOT_DUE_YETPayment is attempted before next-payment-at. Wait for the interval to elapse.
u4003ERR_SUBSCRIPTION_PAUSEDSubscription is paused. Resume it before paying.
u4004ERR_ALREADY_PAUSEDYou tried to pause a subscription that's already paused.
u4005ERR_NOT_PAUSEDYou tried to resume a subscription that isn't paused.

Refund errors

CodeTypeDescription
u5000ERR_REFUND_WINDOW_EXPIREDThe invoice is too old to refund. Refund window is measured from first-payment-at.
u5001ERR_REFUND_EXCEEDS_PAIDYou tried to refund more than the total amount paid on this invoice.
u5002ERR_INVOICE_NOT_PAIDYou can only refund invoices that have received at least one payment.
u5003ERR_INVALID_REFUND_AMOUNTRefund amount must be greater than zero.

Token / transfer errors

CodeTypeDescription
u6000ERR_INVALID_TOKEN_TYPEUnknown token type. Must be u0 (sBTC) or u1 (STX).
u6001ERR_TRANSFER_FAILEDThe underlying token transfer failed — usually means sender has insufficient balance.
u6002ERR_INSUFFICIENT_BALANCESender wallet doesn't have enough of the token to cover the payment or refund.

What to show users

The frontend's CONTRACT_ERRORS map translates these codes into human-friendly messages. When you integrate, check that map first — if you see an error like u5000 in production, you can match it to the appropriate user message ("This invoice is too old to refund") rather than showing the raw code.