Skip to Content
Welcome to the DuckyDux Docs! 🦆
GuidesError Handling & Troubleshooting

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 error
  • request_id: Unique identifier for debugging support requests

Error Categories

StatusCategoryWhen to RetryCommon Types
400Invalid Request❌ Noinvalid-argument
404Not Found❌ Nonot-found
422Validation/Business Logic❌ Novalidation-error, unprocessable-request
429Rate Limited✅ Yes (with backoff)rate-limited
503Service 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 type field 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 allowed
  • RateLimit-Remaining: Requests remaining (will be 0 or negative)
  • RateLimit-Reset: Unix timestamp when quota resets
  • Retry-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-After header 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 null for maxFeePerGas to 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:

  1. PENDING - Bundle created, not yet submitted
  2. SUBMITTED - Sent to block builders, awaiting inclusion
  3. INCLUDED - All transactions successfully included in a block
  4. REVERTED - One or more transactions reverted on-chain
  5. EXPIRED - Bundle missed its target block and was not included
  6. FAILED - 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, or FAILED)

Monitoring Best Practices:

  • Poll GET /v1/bundles/{bundleId} endpoint to check status
  • Set client-side timeout (30-60 seconds recommended)
  • Check the error_message field if status is REVERTED or FAILED
  • If a bundle remains SUBMITTED past its target block, it will eventually transition to EXPIRED
  • 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 timeframe
  • RateLimit-Remaining: Number of available requests remaining
  • RateLimit-Reset: Time remaining (in seconds) until quota resets
  • Retry-After: Seconds to wait before retrying (included in 429 responses)
  • X-RateLimit-Limit-Second: Maximum requests per second
  • X-RateLimit-Limit-Minute: Maximum requests per minute
  • X-RateLimit-Remaining-Second: Requests remaining this second
  • X-RateLimit-Remaining-Minute: Requests remaining this minute

Implementation Requirements:

  1. Check RateLimit-Remaining or X-RateLimit-Remaining-* headers before making requests
  2. Use the Retry-After header value when receiving 429 responses
  3. Implement exponential backoff for retries: min(1000 * 2^attempt, 30000) milliseconds
  4. Limit maximum retry attempts (typically 3-5)
  5. Log rate limit headers for monitoring and debugging

Additional Resources

Last updated on