Quick checks
Run these before you dig into a single error.| Check | How |
|---|---|
| The tree sources are current | Call update() on both tree sources and compare the roots to the pool. |
| The note source sees your notes | Call core.getBalances(). Notes in pending are not spendable yet. |
| The circuit files match the network | Use the files for the network you target. A proof made with the wrong keys fails at the verifier. |
| The addresses match the network | Use the pool, paymaster and asset ids from Network reference. |
| The signer is the right one | proveAddress needs the address that signed the registration message. |
SDK errors
| Message | Likely cause | What to do |
|---|---|---|
Unsupported chainId <id> | The network list in your SDK build does not include this network. HyperEVM is not in 1.4.3. | Use a build that includes it: [SDK_VERSION_WITH_HYPEREVM]. |
Explicit services are required for now | Core got no contractSource, notesSource, commitmentTreeSource or addressTreeSource. | Pass all four. See SDK reference. |
Chosen revoker is not active | The revokerId you passed is inactive or does not exist. | Read the revoker with core.getRevokerData(id) and pick an active one. |
Insufficient balance for asset <id> or Insufficient funds for asset <id> | Your spendable notes for that asset do not cover the amount, or the fee. Notes still in the queue do not count. | Run a tree update, then check getBalances(). On the relayed path the fee comes from the same notes. |
Too many input notes: <n> or Unsupported number of input notes: <n> | The transaction needs more notes than the largest circuit takes. | Merge notes first. Send a transfer to yourself to combine small notes into one. |
Note commitment <c> not found in tree | The commitment tree source is behind or holds the wrong leaves. | Rebuild it from the pool’s events, with a zero leaf for each gap. |
Unable to find shielded address for <address> | The recipient has not registered. | Ask them to register, or send to their 96-byte shielded address. |
Invalid address or ENS name: <value> | to is neither a hex address nor an ENS name. | Check the value. |
Resolved shielded address is malformed | The resolver returned something that is not 96 bytes. | Check the RegisterAddress logs and the deployedBlock you passed. |
Invalid address data length <n> bytes. Expected 96 bytes. | A packed shielded address has the wrong size. | Use account.shieldedAddress.pack(). The unpacked form used for registration is longer. |
DEPOSIT type transactions must have feeAsset as 0 | A deposit has a fee asset. | Set feeAssetId: 0. A deposit never carries a fee. |
Transactions sent via bundler must specify feeAsset as non-zero | viaBundler: true with feeAssetId: 0. | Name the fee asset, or use the wallet path. |
Paymaster address required for viaBundler option | No paymaster in contracts or options. | Pass paymaster. |
userOpFeeQuoteEth is required when using bundler with non-zero feeAssetId | The bundler path needs a fee quote. | Compute one with quoteUserOpGasCostWithLatestBaseFee. |
userOpFeeQuoteEth and requiredPrefundEth must match when both are set | You set the old and new option to different values. | Set only userOpFeeQuoteEth. |
Assets and values should have same length | assetIds and values differ in length. | Fix the arrays. |
WITHDRAW and CONVERT type transactions must have "to" address as string | to is missing or not a string on a withdraw or adaptor call. | Pass a 20-byte public address. |
Only signed transaction can be proved | You skipped signTransaction. | Sign, then prove. |
Circuit path for transact<NN> not found | The transaction needs a circuit shape you did not supply. | Add that circuit’s files to circuits. |
Unsupported fee asset <id> or Failed to get fee estimate for asset <id> | The paymaster cannot price that asset. | Choose an asset the paymaster supports. It needs a price feed. |
relayed and viaBundler are mutually exclusive submission paths | You set both on a build that has relayed. | Set one. |
relayed transactions must name the relayer as paymaster | relayed: true without paymaster. | Pass the relayer address from /quote. |
relayed transactions with a fee asset must supply relayFee | A relayed transaction has a fee asset but no fee. | Pass relayFee, at least the quote. |
Pool errors
These are custom errors from the pool. Decode revert data with the pool ABI.| Error | Likely cause | What to do |
|---|---|---|
DoubleSpend(nullifier) | A note in the transaction was already spent. Your note source is stale, or two transactions used the same note. | Refresh the note source. Wait for the first transaction to land before you start the next. |
UnknownCommitmentTreeRoot or UnknownAddressTreeRoot | The proof used a root the pool no longer keeps. The pool keeps only a short history of roots. | Update the tree sources and prove again. Do not hold a proof for long before you submit it. |
InvalidProof or InvalidTransactionProof | The verifier rejected the proof. Usually the keys do not match the deployed verifier, or an input changed after proving. | Use the circuit files for this network and prove again. |
InvalidRevoker(id) | The revoker id is inactive or unknown. | Use an active revoker. |
UnsupportedAdaptor | The adaptor is not registered with the pool. | Ask for it to be registered. See Integrate a DeFi protocol. |
AdaptorCallFailed(reason) | The adaptor reverted. reason holds the adaptor’s revert data. | Decode reason. Common causes are a failed slippage check and a protocol that is paused. |
InvalidOutputValue(assetId, value, balance) | The adaptor returned more of a token than the handler holds. | Check the amount your adaptor returns. |
InactiveAsset(id) | The asset is not active in the pool. | Use an active asset. Output tokens of an adaptor must be active too. |
DepositBelowMinimum(usd, min) or DepositAboveMaximum(usd, max) | The deposit is outside the allowed range. | Change the amount. Limits are in Status and limits. |
TvlLimitExceeded(projected, limit) | The pool is at its cap on total value. | Try a smaller amount later. |
DepositRestrictedAsAssetFeedNotSet(id) | The pool cannot price this asset yet, so it refuses deposits of it. | Use a different asset. |
PublicAddressAlreadyRegistered(addr) or RootAddressAlreadyRegistered(root) | The address or the shielded account is already registered. | You are done. Do not register again. |
InvalidAddressProof or RootAddrMismatch | The registration proof does not match the signer or the address. | Check that the second argument to proveAddress is the signer of the typed message, and that the message used the pool’s address and chain id. |
SanctionedAddress(addr) | The sender or the signer is on the sanctions list. | The pool will not accept this address. |
UnbackedFee, FeeNotPaidByTransaction, InsufficientFee(given, required) | The fee is not carried by a public asset, is not paid, or is below the required amount. | On the bundler path, recompute the fee quote. On the relayed path, increase it to the quote. |
FeeAssetNotSupportedByVeilnyx(id) or AssetNotSupportedAsFeeAsset(id) | The asset cannot pay fees. | Use a fee asset the paymaster supports. |
DuplicatePubAssetId(id) | The same asset appears twice among the public assets. | List each asset once. |
NativeEthExceedsDeposit or NativeEthProvidedForNonDepositTx | ETH was sent with a call that does not take it, or too much was sent. | Send ETH only with a native deposit, and only the amount the deposit needs. |
NonCanonicalFieldElement(value) | A value in the call is not below the field size. | Pass the SDK’s toSolidityInput() output unchanged. |
InvalidQueueSize, InvalidBatchSize or InvalidSubtreeUpdateProof | The tree update does not match the queue. | Fetch the queue state again and prove a new update. |
ChainlinkPriceFeedNotFound, PriceFeedValueStale or PriceFeedValueInvalid | The price feed for the fee or deposit asset is missing, old or bad. | Try again later or use another asset. |
Relayer errors
Messages from/fund, /gas and /register come straight from the relayer. The checks are listed in Relayer API. The most common:
| Message | Cause |
|---|---|
fee is paid to <address>, not this relayer <address> | The proof names a different paymaster. Read the relayer address from /quote and set it before you prove. |
fee <n> is below the quote <m> | Your fee is under the minimum. |
fee is not carried by a public asset, so the pool would not pay it | The fee asset is not among the transaction’s public assets. |
selector <s> is not sponsored | You sent something other than pool.transact. |
validBefore must be at least 2 minutes ahead | The gas authorization expires too soon. |
queue full (503) | The relayer is busy. Try again. |
relayer rejected the transaction: <reason> | The job was refused or reverted. Nothing was spent on a refusal. |
Private Sub-account problems
| Problem | Cause | What to do |
|---|---|---|
MissingGasError (testnet builder) | A funding withdrawal has margin but no gas. | Add gas to the same withdrawal. Gas funded from the user’s wallet links the two. |
| The funding does not appear on Hyperliquid | It can take minutes to land. | Check the ledger. Do not fund again until you know. |
| Nothing can be returned | The Sub-account holds less than the one-time first transfer charge, the gas fee and the pool minimum. | Fund a larger amount next time. See Private Sub-accounts SDK. |
| The return deposit has no gas | The Sub-account has no HYPE. | Buy gas from the GasStation. |
| A Sub-account’s address differs between mainnet and testnet | The derivation context differs on purpose. | Expected. |
Still stuck
Read the matching source, and check Status and limits for pauses and caps. To report a security problem, emailsecurity@palliora.org. Do not post it in public.