Errors
Every error has this shape:
json
{
"error": "0xabc::game::cheat is not in allowedTargets",
"code": "TARGET_NOT_ALLOWED",
"details": { "target": "0xabc::game::cheat" }
}Branch on code. error is the human-readable reason and details, when present, names the offending input. Errors are not wrapped in data.
The tank pays nothing for a rejected transaction. The fee applies only after the sponsor signs and the transaction executes.
400 - the request is malformed
| Code | Fix |
|---|---|
EMPTY_TRANSACTION_BYTES | Send transactionBytes as a non-empty base64 string. |
INVALID_TRANSACTION_BYTES | Send the exact bytes from tx.build(). Do not edit or re-encode them. |
TRANSACTION_TOO_LARGE | The bytes exceed 128 KB. Split the transaction. |
NON_CANONICAL_TRANSACTION_BYTES | The bytes have trailing or non-canonical data. Rebuild with the SDK. |
UNSUPPORTED_TRANSACTION_KIND | Only programmable transactions are sponsored. |
UNSUPPORTED_EXPIRATION | Use setExpiration({ ValidDuring: {...} }). |
EXPIRATION_REQUIRED | Set ValidDuring with a maxEpoch. |
EXPIRATION_TOO_FAR | Set maxEpoch to epoch + 1. |
GAS_PAYMENT_MUST_BE_EMPTY | Call setGasPayment([]). The tank pays from its address balance. |
EMPTY_SIGNATURE | Send userSignature as a non-empty string. |
INVALID_SIGNATURE_ENCODING | Send the serialized signature the wallet returned, base64. |
UNSUPPORTED_SIGNATURE_SCHEME | Use Ed25519, Secp256k1, Secp256r1, MultiSig, or zkLogin. |
INVALID_SIGNATURE | The signature does not match the bytes. Sign the exact bytes you submit. |
INVALID_TANK_NAME | Tank names are 1 to 32 lower-case letters, digits, and hyphens. |
402 - the tank cannot pay
| Code | Fix |
|---|---|
INSUFFICIENT_TANK_FUNDS | Top up the tank. Deposits are credited within a minute. |
403 - a security check or a rule said no
Security checks protect the tank. They cannot be turned off.
| Code | Fix |
|---|---|
INSUFFICIENT_SCOPE | Use an API key with the Sponsor scope. |
SENDER_IS_SPONSOR_ADDRESS | The sender is a tank address. Use the user's address as sender. |
WITHDRAW_FROM_NOT_SENDER | Funds withdrawals must come from the sender, never from the gas owner. |
GAS_COIN_ARGUMENT | Do not use tx.gas as an argument. The gas coin belongs to the tank. |
ADDRESS_ALIAS_CALL | Calls to 0x2::address_alias are not sponsored. |
ADDRESS_ALIAS_STATE_INPUT | The alias state object 0xa cannot be an input. |
TOO_MANY_WITHDRAW_RESERVATIONS | Use at most 9 balance withdrawals in one transaction. |
GAS_PRICE_TOO_HIGH | Set the gas price to at most 5 times config.gasPrice. |
BUDGET_EXCEEDS_TANK_MAX | Set the budget to at most config.maxGasBudgetMist. |
Rule codes name the rule. Fix the transaction or edit the rule in the dashboard.
| Code | Rule |
|---|---|
SENDER_NOT_ALLOWED | allowedSenders |
TARGET_NOT_ALLOWED | allowedTargets |
RECIPIENT_NOT_ALLOWED | allowedRecipients |
RECIPIENT_NOT_STATIC | allowedRecipients needs a plain address input, not a command result |
COIN_TYPE_NOT_ALLOWED | allowedCoinTypes |
TRANSFER_LIMIT_EXCEEDED | maxTransferMistPerCoinType |
PUBLISH_NOT_ALLOWED | allowPublish |
404 - no such tank
| Code | Fix |
|---|---|
TANK_NOT_FOUND | Check the tank name and that the API key belongs to the tank's project. |
409 - the transaction does not match the tank
| Code | Fix |
|---|---|
GAS_OWNER_MISMATCH | Call setGasOwner(config.sponsorAddress) for the tank you submit to. |
TANK_NETWORK_MISMATCH | The tank is on another network than the API key. Use the matching base URL. |
TANK_INACTIVE | The tank is paused, frozen, or deleted. Check the dashboard. |
CHAIN_ID_MISMATCH | Set chain in ValidDuring to config.chainIdentifier. |
410 - too late
| Code | Fix |
|---|---|
TRANSACTION_EXPIRED | The epoch passed maxEpoch. Re-read the config, rebuild, and sign again. |
REPLAYED_DIGEST | This digest was already submitted. Build a new transaction with a new nonce. |
422 - the chain says no
| Code | Fix |
|---|---|
NOT_YET_VALID | minEpoch is in the future. Use config.epoch. |
GAS_PRICE_BELOW_REFERENCE | Set the gas price to at least config.gasPrice. |
SIMULATION_FAILED | The transaction aborts in simulation. Fix the transaction. Nothing was charged. |
SIMULATION_REJECTED | The node rejected the transaction before execution. Read message. |
NODE_REJECTED | The node rejected the signed transaction. Read message. Nothing was charged. |
429 - a cap was reached
| Code | Fix |
|---|---|
DAILY_CAP_EXCEEDED | Wait for dailyResetsAt or raise dailyCapMist. |
SENDER_CAP_EXCEEDED | This sender reached maxSponsorshipsPerSenderPerDay. Wait for the UTC day. |
PLAN_CAP_EXCEEDED | The free plan allows 10 sponsorships per month per network. Upgrade the plan. |
(no code, error is Rate limit exceeded) | The plan's request rate limit. Slow down or upgrade. See retryAfter. |
503 - try again later
| Code | Fix |
|---|---|
SPONSORSHIP_DISABLED | Inodra paused sponsorship. config.sponsorshipAvailable is false. Retry later. |
CHAIN_UNAVAILABLE | Inodra cannot reach the network. Rebuild with a new nonce, then retry with backoff. |
VALIDATION_FAILED | The request body did not match the schema. details lists the fields. |
SIMULATION_UNAVAILABLE | Simulation is required by your rules and the node is down. Retry with backoff. |
202 is not an error
A 202 with "status": "pending" in data means the transaction was sent and Inodra lost the result. Poll GET /v1/gas/transactions/{digest}. See the pending case.