Error Handling Guide
Robust error handling is essential for production applications using the DuckyDux API. This guide covers implementation patterns, common scenarios, and proven solutions.
For a complete reference of all API error types, see the API Errors Reference.
Understanding API Errors
The DuckyDux API follows RFC 9457 for structured error responses. All errors include:
type: URI identifying the error type (for programmatic handling)status: HTTP status code (400, 422, 429, 503, etc.)detail: Human-readable explanation of this specific errorrequest_id: Unique identifier for debugging support requests
Error Categories
| Status | Category | When to Retry | Common Types |
|---|---|---|---|
400 | Invalid Request | ❌ No | invalid-argument |
404 | Not Found | ❌ No | not-found |
422 | Validation/Business Logic | ❌ No | validation-error, unprocessable-request |
429 | Rate Limited | ✅ Yes (with backoff) | rate-limited |
503 | Service Unavailable | ✅ Yes (with backoff) | operation-unavailable, timeout |
Swap Quote Errors
No Route Found
Error Type: unprocessable-request (422)
Cause: Insufficient liquidity or no trading path exists between the requested token pair.
How It Occurs: The API attempts to find optimal routes through available liquidity pools. When no viable path exists or liquidity is insufficient for the requested amount, the request is rejected.
Solution Strategy:
- Implement a fallback mechanism that progressively reduces the swap amount (e.g., try 100%, 80%, 50% of the original amount)
- Parse the error
typefield to identify route-finding failures specifically - Consider alternative token pairs or intermediate hops if direct routes consistently fail
Slippage Too Restrictive
Error Type: unprocessable-request (422)
Cause: The slippage tolerance is too low for current market conditions.
How It Occurs: When the calculated price impact exceeds your specified slippage tolerance, the quote request is rejected to prevent unfavorable trades.
Solution Strategy:
- Implement adaptive slippage by trying progressively higher values (0.1%, 0.5%, 1%, 2%, 5%)
- Warn users when high slippage is required, as it indicates volatile markets or low liquidity
- Check if the error detail contains “slippage” to differentiate from other unprocessable requests
Invalid Token Address
Error Type: invalid-argument (400)
Cause: Ethereum address format is malformed or doesn’t match the expected pattern.
How It Occurs: All addresses must match the format 0x followed by 40 hexadecimal characters.
Solution Strategy:
- Validate addresses client-side using the regex pattern
^0x[a-fA-F0-9]{40}$before making API calls - Implement checksum validation using libraries like ethers.js or web3.js
- Provide clear error messages to users about invalid address format
Bundle Execution Errors
Transaction Simulation Failure
Error Type: unprocessable-request (422)
Problem: Bundle transactions fail pre-submission validation.
How It Occurs: Before accepting a bundle, the API simulates all transactions against the current blockchain state. If any transaction would revert, the entire bundle is rejected.
Common Causes:
- Insufficient token balances or allowances
- Contract execution will revert (e.g., slippage check fails)
- Invalid contract call parameters
- Dependent transactions in wrong order
- Gas limit too low for complex operations
Error Details: The error message includes the transaction index and revert reason: "Transaction #2 failed simulation: insufficient allowance"
Solution Strategy:
- Validate all preconditions before bundle submission (balances, approvals, nonces)
- Test transaction order - ensure dependencies execute first
- Increase gas limits if simulation fails due to out-of-gas
- Parse the error message to identify which transaction failed and why
Transaction Decoding Failure
Error Type: unprocessable-request (422)
Problem: Unable to decode RLP-encoded raw transactions.
How It Occurs: Transactions must be properly RLP-encoded with valid signatures. Malformed encoding or invalid signatures cause immediate rejection.
Common Causes:
- Malformed RLP encoding
- Incorrect transaction signature
- Missing required transaction fields (nonce, gas, etc.)
- Wrong chain ID in signature
Solution Strategy:
- Use established Web3 libraries (ethers.js, web3.py) to serialize transactions
- Verify transaction signature before submission
- Ensure correct chain ID is used when signing (Ethereum mainnet: 1)
- Test transaction encoding/decoding locally before API submission
Duplicate Bundle Submission
Behavior: Bundle with identical transactions and target block already exists.
How It Works: Each bundle is assigned a unique hash based on its transaction content and target block. If you submit a bundle with the same hash, the API returns the existing bundle’s details instead of creating a duplicate.
Response: The existing bundle’s current status and ID are returned.
Solution Strategy:
- Cache bundle IDs client-side based on transaction content and target block
- Poll the existing bundle’s status instead of resubmitting
- Only create a new bundle if the original has expired or failed
Rate Limit Exceeded
Error Type: rate-limited (429)
Problem: One or more transaction senders in the bundle have exceeded their rate limit quota.
How It Occurs: Rate limits are applied per sender address. Each unique sender address has its own quota.
Response Headers:
RateLimit-Policy: Describes the limit policy (“100 per minute”)RateLimit-Limit: Maximum requests allowedRateLimit-Remaining: Requests remaining (will be 0 or negative)RateLimit-Reset: Unix timestamp when quota resetsRetry-After: Seconds to wait before retrying
Solution Strategy:
- Track rate limits per sending address, not per API client
- Distribute transactions across multiple sender addresses if needed
- Respect the
Retry-Afterheader value before resubmitting - Implement exponential backoff for retries
Insufficient Relayer Funds (Sponsored Bundles)
Error Type: operation-unavailable (503)
Problem: No relayer with sufficient balance available to sponsor the bundle.
How It Occurs: Sponsored bundles require a relayer to prefund transactions. If no relayer has enough ETH to cover the prefund amounts plus gas costs, the request fails.
Solution Strategy:
- Request smaller sponsor amounts if possible
- Implement retry logic with exponential backoff (relayers may become available)
- Monitor your usage patterns - if this occurs frequently, contact support
- Consider reducing the number of sponsored accounts per bundle
Invalid Gas Price (Sponsored Bundles)
Error Type: invalid-argument (400)
Problem: The provided maxFeePerGas is lower than current network requirements.
How It Occurs: The minimum fee must cover the current base fee plus priority fee. If your specified maximum is below this, the transaction cannot be processed.
Error Message Format: "Max fee per gas is lower than required minimum"
Solution Strategy:
- Query current gas prices before bundle submission
- Add a buffer (10-20%) above minimum required fees
- Allow dynamic fee adjustment based on network conditions
- Use
nullformaxFeePerGasto let the API calculate appropriate fees automatically
Insufficient Repayment (Sponsored Bundles)
Error Type: invalid-argument (400)
Problem: The sum of repayment amounts is less than the required minimum.
How It Occurs: Gas sponsorship requires repayment of gas costs plus a service fee. If your specified repayments don’t cover the total cost, the bundle is rejected.
Error Message Format: "Minimum repayment (X) is higher than repayment sum (Y)"
Solution Strategy:
- Always get a fresh sponsorship quote before bundle submission
- Add a safety margin (5-10%) to quoted repayment amounts
- Ensure swap outputs are sufficient to cover repayments
- Account for potential gas price increases between quote and execution
Bundle Status Tracking
Bundle Lifecycle States:
PENDING- Bundle created, not yet submittedSUBMITTED- Sent to block builders, awaiting inclusionINCLUDED- All transactions successfully included in a blockREVERTED- One or more transactions reverted on-chainEXPIRED- Bundle missed its target block and was not includedFAILED- Submission to builders failed
How Status Tracking Works:
- The API continuously monitors submitted bundles by checking transaction receipts on each new block
- Status transitions are permanent and don’t rollback
- Bundles are automatically tracked until they reach a final state (
INCLUDED,REVERTED,EXPIRED, orFAILED)
Monitoring Best Practices:
- Poll
GET /v1/bundles/{bundleId}endpoint to check status - Set client-side timeout (30-60 seconds recommended)
- Check the
error_messagefield if status isREVERTEDorFAILED - If a bundle remains
SUBMITTEDpast its target block, it will eventually transition toEXPIRED - Expired bundles indicate builder rejection or network congestion - consider resubmitting with higher priority fees
Sponsorship Errors
Insufficient Repayment Capacity
Problem: User won’t receive enough tokens to cover gas sponsorship repayment.
How It Occurs: After a sponsored swap executes, the user must repay the gas costs. If the swap output is insufficient, the transaction will revert.
Solution Strategy:
- Calculate the expected swap output and convert to ETH value
- Compare against the required repayment from the sponsorship quote
- Add a safety margin (10-20%) to account for price slippage
- Reject swaps where output is insufficient to cover repayment plus margin
- Account for the service fee percentage in your calculations
Quote Expiry
Problem: Sponsorship quotes become stale before transaction submission.
How It Occurs: Gas prices and network conditions change rapidly. A quote that was valid 2 minutes ago may no longer be accurate.
Solution Strategy:
- Implement client-side quote caching with short TTL (30-60 seconds)
- Refresh quotes before bundle submission if they’re older than the TTL
- Handle failed sponsorship by fetching a new quote and retrying
- Consider network congestion when determining quote validity period
- In high-volatility periods, use even shorter TTLs (15-30 seconds)
Rate Limiting and Retry Strategies
Exponential Backoff
Error Type: rate-limited (429)
How Rate Limiting Works: The API uses a sliding window algorithm to enforce request quotas. When you exceed your limit, you receive a 429 response with headers indicating when you can retry.
For detailed information about rate limits per endpoint group, see the Rate Limits Reference.
Rate Limit Headers:
RateLimit-Limit: Allowed limit in the current timeframeRateLimit-Remaining: Number of available requests remainingRateLimit-Reset: Time remaining (in seconds) until quota resetsRetry-After: Seconds to wait before retrying (included in 429 responses)X-RateLimit-Limit-Second: Maximum requests per secondX-RateLimit-Limit-Minute: Maximum requests per minuteX-RateLimit-Remaining-Second: Requests remaining this secondX-RateLimit-Remaining-Minute: Requests remaining this minute
Implementation Requirements:
- Check
RateLimit-RemainingorX-RateLimit-Remaining-*headers before making requests - Use the
Retry-Afterheader value when receiving 429 responses - Implement exponential backoff for retries:
min(1000 * 2^attempt, 30000)milliseconds - Limit maximum retry attempts (typically 3-5)
- Log rate limit headers for monitoring and debugging