Api

Error Codes

Complete error reference

This document provides a comprehensive reference for all error codes in the Hydra API.

gRPC Status Codes

Hydra uses standard gRPC status codes. All errors follow this format:

{
  "code": 3,
  "message": "invalid asset id",
  "details": []
}

Common Status Codes

OK (0)

Description: Success - no error

When it occurs: Successful operation

Action: None required


CANCELLED (1)

Description: Operation was cancelled

When it occurs:

  • Client cancelled request
  • Stream was closed

Action: Retry if needed


UNKNOWN (2)

Description: Unknown error

When it occurs:

  • Unexpected server error
  • Unhandled exception

Action: Check request parameters, contact support if persists


INVALID_ARGUMENT (3)

Description: Client specified an invalid argument

Common causes:

  • Invalid asset ID format
  • Invalid network parameters
  • Malformed request data
  • Out-of-range values

Examples:

// Error: invalid asset id
{
  "code": 3,
  "message": "invalid asset id"
}

// Error: invalid network
{
  "code": 3,
  "message": "unsupported network protocol"
}

// Error: invalid amount
{
  "code": 3,
  "message": "amount must be positive"
}

Action:

  • Verify asset ID format (e.g., "BTC" for Bitcoin, "0x..." for Ethereum)
  • Check network protocol and chain_id
  • Validate all numeric values
  • Ensure required fields are present

DEADLINE_EXCEEDED (4)

Description: Operation timed out

When it occurs:

  • Request took too long (>10 seconds for most operations)
  • Network latency issues

Action:

  • Retry with exponential backoff
  • Check network connectivity
  • For long operations, use streaming endpoints

NOT_FOUND (5)

Description: Requested resource not found

Common causes:

  • Transaction doesn't exist
  • Order not found
  • Channel doesn't exist
  • Payment not found

Examples:

// Error: transaction not found
{
  "code": 5,
  "message": "transaction not found: abc123..."
}

// Error: order not found
{
  "code": 5,
  "message": "order not found: order_xyz789"
}

Action:

  • Verify resource ID is correct
  • Check that resource exists on the specified network
  • Ensure resource hasn't been deleted

ALREADY_EXISTS (6)

Description: Resource already exists

When it occurs:

  • Attempting to create duplicate resource
  • Market already initialized
  • Channel already opened

Examples:

{
  "code": 6,
  "message": "market already initialized"
}

Action:

  • Check if resource already exists
  • Use update/modify operations instead of create

PERMISSION_DENIED (7)

Description: Caller doesn't have permission

When it occurs:

  • Authentication failure
  • Insufficient permissions
  • Attempting to access another user's resource

Action:

  • Verify authentication credentials
  • Check API key permissions
  • Ensure you own the resource

RESOURCE_EXHAUSTED (8)

Description: Resource has been exhausted

Common causes:

  • Insufficient balance
  • No liquidity available
  • Rental capacity exceeded
  • Channel capacity full

Examples:

// Error: insufficient balance
{
  "code": 8,
  "message": "insufficient onchain balance"
}

// Error: no liquidity
{
  "code": 8,
  "message": "no liquidity available in orderbook"
}

// Error: rental capacity
{
  "code": 8,
  "message": "rental amount exceeds available liquidity"
}

Action:

  • Check balance before operations
  • Add funds to wallet
  • Try smaller amount
  • Wait for liquidity to become available

FAILED_PRECONDITION (9)

Description: Operation rejected due to system state

Common causes:

  • Channel not active yet
  • Market not initialized
  • Asset not supported
  • Duration out of allowed range

Examples:

// Error: channel not ready
{
  "code": 9,
  "message": "channel not active for sending"
}

// Error: market not initialized
{
  "code": 9,
  "message": "market not initialized for this pair"
}

// Error: duration invalid
{
  "code": 9,
  "message": "rental duration below minimum"
}

Action:

  • Wait for prerequisite conditions
  • Initialize required resources first
  • Check state before operations
  • Verify parameter ranges

ABORTED (10)

Description: Operation was aborted

When it occurs:

  • Concurrent modification conflict
  • Transaction conflict
  • Order already cancelled

Action: Retry operation


OUT_OF_RANGE (11)

Description: Operation outside valid range

Common causes:

  • Amount too large or too small
  • Fee rate invalid
  • Duration out of range

Action:

  • Check minimum/maximum values
  • Adjust parameters to valid range

UNIMPLEMENTED (12)

Description: Operation not implemented

When it occurs:

  • Feature not yet available
  • Endpoint deprecated
  • Network not supported

Action:

  • Check API documentation for supported features
  • Use alternative endpoint

INTERNAL (13)

Description: Internal server error

When it occurs:

  • Database error
  • Backend service failure
  • Unexpected server condition

Action:

  • Retry with exponential backoff
  • Contact support if persists

UNAVAILABLE (14)

Description: Service temporarily unavailable

Common causes:

  • Service maintenance
  • Network issues
  • Backend overload

Action:

  • Retry with exponential backoff
  • Check status page
  • Wait and retry

DATA_LOSS (15)

Description: Unrecoverable data loss

When it occurs: Rare - serious server issue

Action: Contact support immediately


UNAUTHENTICATED (16)

Description: Request lacks valid authentication

When it occurs:

  • Missing authentication
  • Invalid credentials
  • Expired session

Action:

  • Provide authentication credentials
  • Refresh authentication token
  • Check API key is valid

Error Handling Best Practices

1. Implement Retry Logic

async function withRetry<T>(
  operation: () => Promise<T>,
  maxRetries: number = 3,
  baseDelay: number = 1000
): Promise<T> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await operation()
    } catch (error) {
      const code = error.code

      // Don't retry client errors
      if (code === 3 || code === 5 || code === 7) {
        throw error
      }

      // Retry on server errors or timeouts
      if (code === 13 || code === 14 || code === 4) {
        const delay = baseDelay * Math.pow(2, i)
        console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms`)
        await new Promise(resolve => setTimeout(resolve, delay))
        continue
      }

      throw error
    }
  }

  throw new Error('Max retries exceeded')
}

// Usage
const balance = await withRetry(() =>
  walletClient.getBalance(request, {})
)

2. Graceful Error Handling

async function safeGetBalance(
  client: WalletServiceClient,
  network: Network,
  assetId: string
): Promise<Balance | null> {
  try {
    const request = new GetBalanceRequest()
    request.setNetwork(network)
    request.setAssetId(assetId)

    const response = await client.getBalance(request, {})
    return response.getBalance()
  } catch (error) {
    switch (error.code) {
      case 3:
        console.error('Invalid asset ID:', assetId)
        return null

      case 5:
        console.error('Asset not found:', assetId)
        return null

      case 14:
        console.warn('Service unavailable, retrying...')
        // Implement retry logic
        return null

      default:
        console.error('Unexpected error:', error)
        throw error
    }
  }
}

3. Check Preconditions

async function sendPaymentSafely(
  walletClient: WalletServiceClient,
  nodeClient: NodeServiceClient,
  network: Network,
  assetId: string,
  amount: string
) {
  // Check balance first
  const balanceReq = new GetBalanceRequest()
  balanceReq.setNetwork(network)
  balanceReq.setAssetId(assetId)

  const balanceResp = await walletClient.getBalance(balanceReq, {})
  const available = balanceResp.getBalance()?.getOffchain()?.getLocal()

  if (BigInt(available || '0') < BigInt(amount)) {
    throw new Error('Insufficient balance')
  }

  // Proceed with payment
  const paymentReq = new SendPaymentRequest()
  // ... configure payment
  return await nodeClient.sendPayment(paymentReq, {})
}

4. User-Friendly Messages

function getUserFriendlyError(error: any): string {
  switch (error.code) {
    case 3:
      return 'Invalid input. Please check your entries.'

    case 5:
      return 'Resource not found. Please verify the ID.'

    case 8:
      if (error.message.includes('balance')) {
        return 'Insufficient funds. Please add more to your wallet.'
      }
      if (error.message.includes('liquidity')) {
        return 'Not enough liquidity available. Try a smaller amount.'
      }
      return 'Resource limit exceeded.'

    case 9:
      return 'Operation cannot be completed right now. Please try again later.'

    case 14:
      return 'Service temporarily unavailable. Please try again in a moment.'

    default:
      return 'An unexpected error occurred. Please try again.'
  }
}

// Usage in UI
try {
  await client.someOperation(request, {})
} catch (error) {
  alert(getUserFriendlyError(error))
}

Service-Specific Errors

Wallet Service

ErrorCauseSolution
INVALID_ARGUMENT: invalid asset idWrong asset ID formatCheck asset ID for network type
NOT_FOUND: transaction not foundTransaction doesn't existVerify txid is correct

Orderbook Service

ErrorCauseSolution
RESOURCE_EXHAUSTED: no liquidityEmpty orderbookWait or provide liquidity
FAILED_PRECONDITION: market not initializedMarket doesn't existCall InitMarket first
INVALID_ARGUMENT: amount below minimumAmount too smallIncrease to min_base_amount

Swap Service

ErrorCauseSolution
RESOURCE_EXHAUSTED: insufficient balanceNot enough offchain fundsUse SimpleSwap instead
FAILED_PRECONDITION: price exceeded tolerancePrice moved too muchIncrease tolerance or retry

Node Service

ErrorCauseSolution
FAILED_PRECONDITION: channel not activeChannel still openingUse WaitForActiveAssetChannel
NOT_FOUND: channel not foundInvalid channel_idVerify channel exists
RESOURCE_EXHAUSTED: insufficient capacityChannel too smallDeposit more funds

Rental Service

ErrorCauseSolution
RESOURCE_EXHAUSTED: rental capacity exceededAmount too largeReduce rental amount
FAILED_PRECONDITION: duration out of rangeInvalid durationUse allowed duration range

Debugging Tips

  1. Enable verbose logging - Log all requests and responses
  2. Check error.message - Contains detailed error information
  3. Verify request format - Use protobuf debugging tools
  4. Test with small amounts - Use minimal values when debugging
  5. Check network status - Ensure blockchain is synced
  6. Monitor rate limits - Avoid excessive requests

← Back to API Reference | Next: API Reference →


Copyright © 2025