Error Codes Reference
Complete reference for all error codes in the FLUID Network API. Use this guide to understand, handle, and troubleshoot errors in your integration.
Error Code Ranges
FLUID Network uses structured error codes organized by category:
| Range | Category | Description |
|---|---|---|
| 1000-1999 | General Application | Authentication, validation, rate limiting, HTTP errors |
| 2000-2999 | Integration/Connector | Bank connector, upstream service errors |
| 3000-3999 | Transaction Processing | Transaction lifecycle, status, and validation errors |
| 4000-4999 | Webhook/Notification | Webhook delivery and subscription errors |
| 5000-5999 | Settlement/Batch | Settlement batch processing errors |
Error Response Format
All API errors follow this structure:
{
"success": false,
"error": {
"code": 3009,
"message": "Insufficient funds",
"category": "accounts",
"details": {
"transaction_id": "txn_abc123",
"account_number": "024XXXXXXXX"
}
}
}General Application Errors (1000-1999)
Core Application Errors
| Code | Message | Category | Description | HTTP Status |
|---|---|---|---|---|
| 1000 | An unexpected error occurred | general | Unknown server error - contact support if persists | 500 |
| 1007 | Validation failed | validation | Request validation failed - check error details | 422 |
HTTP Request Errors (1400-1499)
| Code | Message | Category | Description | HTTP Status |
|---|---|---|---|---|
| 1400 | Bad request | request | Malformed request syntax or invalid parameters | 400 |
| 1401 | Unauthorized | authentication | Missing or invalid authentication credentials | 401 |
| 1403 | Forbidden | authorization | Authenticated but insufficient permissions | 403 |
| 1404 | Resource not found | general | Requested resource does not exist | 404 |
| 1405 | Method not allowed | request | HTTP method not supported for this endpoint | 405 |
| 1409 | Request conflicts with current state | general | Resource state conflict (e.g., duplicate operation) | 409 |
| 1422 | Invalid record | validation | ActiveRecord validation failed | 422 |
| 1429 | Too many requests | rate_limiting | Rate limit exceeded - retry after cooldown | 429 |
| 1500 | Internal server error | general | Unexpected server error | 500 |
| 1503 | Service temporarily unavailable | availability | Service is down for maintenance or overloaded | 503 |
Security Errors (1450-1499)
| Code | Message | Category | Severity | Description | HTTP Status |
|---|---|---|---|---|---|
| 1451 | IP address not authorized | security | high | Your IP is not whitelisted for this partner | 403 |
| 1452 | IP address validation failed | security | medium | IP validation check failed | 403 |
| 1453 | Rate limit exceeded for IP address | security | medium | Too many requests from your IP | 429 |
| 1454 | Rate limit exceeded for payment partner | security | medium | Partner-level rate limit exceeded | 429 |
| 1455 | Rate limit exceeded for bank | security | medium | Bank-level rate limit exceeded | 429 |
| 1456 | Payment processing rate limit exceeded | security | high | Critical payment processing limit hit | 429 |
Rate Limiting Response: When you receive rate limit errors (1453-1456), implement exponential backoff. See Rate Limiting Guide for details.
HMAC Authentication Errors (1400-1499)
| Code | Message | Category | Severity | Description | HTTP Status |
|---|---|---|---|---|---|
| 1401 | HMAC signature required | authentication | high | Missing X-Signature header | 401 |
| 1401 | Invalid HMAC signature | authentication | high | Signature verification failed - check secret key | 401 |
| 1401 | Request timestamp expired | authentication | high | Timestamp older than 5 minutes (replay protection) | 401 |
| 1401 | Request timestamp required | authentication | high | Missing X-Timestamp header | 401 |
| 1400 | Invalid timestamp format | validation | medium | Timestamp must be Unix epoch (seconds) | 400 |
HMAC Signature Debugging: If you receive signature errors, verify:
- You're using the correct secret key from the dashboard
- The signature string is built correctly:
method + path + timestamp + body - The timestamp matches what you sent in
X-Timestamp - Request body is sent as raw JSON (not form-encoded)
See HMAC Authentication Guide for implementation examples.
Integration/Connector Errors (2000-2999)
| Code | Message | Category | Description | HTTP Status | Retry? |
|---|---|---|---|---|---|
| 2001 | Bank connector error | connectors | Bank integration layer error | 502 | Yes (exponential backoff) |
| 2002 | Bank API error | connectors | Bank's API returned an error | 502 | Depends on bank error |
| 2003 | No connector available for bank | connectors | Bank integration not configured | 503 | No |
| 2408 | Upstream service timeout | connectors | Bank/upstream service timed out | 504 | Yes (after delay) |
| 2500 | Upstream service error | connectors | Upstream service returned error | 502 | Yes (exponential backoff) |
| 2502 | Upstream connection failed | connectors | Cannot connect to upstream service | 502 | Yes (exponential backoff) |
Connector Errors: Connector errors (2xxx) indicate issues with bank integrations or upstream services. These are typically transient:
- Retry strategy: Exponential backoff (1s, 2s, 4s, 8s)
- Max retries: 3 attempts
For persistent errors, contact support with the transaction ID.
Transaction Processing Errors (3000-3999)
| Code | Message | Category | Description | HTTP Status | Action Required |
|---|---|---|---|---|---|
| 3001 | Invalid status transition | transactions | Cannot transition between these statuses | 400 | Check current transaction status |
| 3002 | Invalid approval method | transactions | Approval method not supported for this transaction | 400 | Use supported approval method |
| 3003 | Duplicate transaction reference | transactions | Transaction with this reference already exists | 409 | Use unique reference or retrieve existing |
| 3004 | Unsupported currency | transactions | Currency not supported (must be GHS) | 400 | Use GHS only |
| 3005 | Transaction limit exceeded | transactions | Amount exceeds configured limits | 400 | Check partner limits in dashboard |
| 3006 | Transaction already processed | transactions | Transaction is already complete/failed | 409 | Check transaction status |
| 3007 | Invalid transaction amount | transactions | Amount is zero, negative, or exceeds max | 400 | Validate amount (min: 1.00) |
| 3008 | Account is inactive | accounts | Customer account is inactive/blocked | 400 | Verify account status with bank |
| 3009 | Insufficient funds | accounts | Customer account has insufficient balance | 400 | Customer needs to fund account |
| 3404 | Transaction not found | transactions | Transaction ID does not exist | 404 | Verify transaction ID |
Idempotency: When you receive error 3003 (duplicate reference), your transaction may already be processing. Always:
- Use the same reference for retries of the same payment
- Call
GET /debit-requests/:referenceto check status before retrying - Never create new references for the same payment
See Idempotency Guide for best practices.
Transaction Status Transitions
Valid status transitions (violating these causes error 3001):
See Status Codes Reference for complete status definitions.
Webhook/Notification Errors (4000-4999)
| Code | Message | Category | Description | HTTP Status | Action Required |
|---|---|---|---|---|---|
| 4001 | Webhook delivery failed | webhooks | Failed to deliver webhook to your URL | 502 | Ensure endpoint returns 200 |
| 4400 | Invalid webhook payload | webhooks | Webhook payload validation failed | 400 | Check webhook signature/payload |
| 4401 | Invalid webhook signature | webhooks | Webhook signature verification failed | 401 | Verify using webhook secret |
| 4403 | Partner not subscribed to event | webhooks | You're not subscribed to this event type | 403 | Enable event in dashboard |
| 4404 | Webhook not configured for partner | webhooks | No webhook URL configured | 404 | Configure webhook URL in dashboard |
| 4408 | Webhook delivery timeout | webhooks | Your webhook endpoint timed out (>30s) | 408 | Optimize webhook handler |
Webhook Best Practices: To avoid webhook errors:
- Return 200 quickly: Process webhooks asynchronously (queue for background processing)
- Verify signatures: Always validate
X-Signatureheader before processing - Handle retries: Webhooks retry up to 5 times with exponential backoff
- Idempotent handling: Use
event_idto deduplicate webhook events
See Webhook Overview for implementation guide.
Settlement/Batch Errors (5000-5999)
| Code | Message | Category | Description | HTTP Status | Action Required |
|---|---|---|---|---|---|
| 5001 | Settlement batch cannot be processed | settlements | Batch is in invalid state for processing | 400 | Check batch status |
| 5002 | No transactions to settle | settlements | Batch contains no eligible transactions | 400 | Verify transactions in batch |
| 5003 | Settlement currency not supported | settlements | Currency not supported for settlements | 400 | Use GHS only |
| 5004 | Settlement line item transaction type invalid | settlements | Transaction type cannot be settled | 400 | Only debit transactions can be settled |
| 5005 | Settlement batch already processed | settlements | Batch has already been processed | 409 | Check batch status |
| 5404 | Settlement batch not found | settlements | Batch ID does not exist | 404 | Verify batch ID |
Error Handling Patterns
Pattern 1: Basic Error Handling
When making API requests, implement error handling that:
- Catches HTTP errors from the API response
- Extracts error details from the response body (
code,message,category) - Handles specific error codes with appropriate logic:
- 3009 (Insufficient funds): Notify customer to fund their account
- 3003 (Duplicate reference): Check existing transaction status instead of creating new one
- 1429 (Rate limit): Wait briefly and retry the request
- Logs error information for debugging and monitoring
- Propagates unhandled errors to higher-level error handlers
Implementation approach:
- Use try-catch blocks around API calls
- Check if error response contains structured error data
- Use switch/case or if-else to handle specific error codes
- Implement appropriate recovery actions for each error type
Pattern 2: Retry Logic with Exponential Backoff
For transient errors (network issues, rate limits, temporary service unavailability), implement retry logic with exponential backoff:
Key implementation steps:
- Attempt the API call and catch errors
- Identify retryable errors by checking error codes:
- 2001, 2002, 2408, 2500, 2502 (connector/integration errors)
- 1429 (rate limiting)
- Calculate delay using exponential backoff formula:
base_delay * (2 ^ attempt_number)- Attempt 0: 1 second
- Attempt 1: 2 seconds
- Attempt 2: 4 seconds
- Wait for the delay before retrying
- Limit total retry attempts (recommended: 3 retries maximum)
- Throw error if all retries are exhausted
Logic flow:
for each attempt (0 to max_retries):
try:
execute API call
return successful result
catch error:
if error is not retryable:
throw error immediately
if last attempt:
throw error (no more retries)
calculate delay = base * (2 ^ attempt)
wait for delay
continue to next attemptThis pattern prevents overwhelming the API during temporary outages while giving enough time for services to recover.
Pattern 3: Handling Validation Errors
When validation fails (error codes 1007 or 1422), the error response includes field-specific validation details in the details object.
Error response structure for validation errors:
{
"success": false,
"error": {
"code": 1007,
"message": "Validation failed",
"category": "validation",
"details": {
"amount": ["must be greater than 0"],
"currency": ["must be GHS"],
"phone_number": ["is required"]
}
}
}Handling approach:
- Check error code for 1007 (validation failed) or 1422 (invalid record)
- Extract field errors from the
detailsobject - Iterate through field errors to display user-friendly messages
- Map to UI fields if showing errors in a form
- Log validation errors for debugging incorrect API usage
This allows you to show specific validation errors for each field rather than a generic "validation failed" message.
Troubleshooting Guide
Authentication Issues
Problem: Receiving error 1401 (Unauthorized)
Solutions:
- Verify API key is correct and active in dashboard
- Check
Authorization: Bearer YOUR_API_KEYheader format - Ensure you're using the correct environment (sandbox vs production)
- Confirm API key has necessary permissions for the endpoint
Problem: HMAC signature errors (1401 - Invalid HMAC signature)
Solutions:
- Verify signature string construction:
METHOD + PATH + TIMESTAMP + BODY - Ensure timestamp in signature matches
X-Timestampheader - Check timestamp is recent (within 5 minutes)
- Use raw JSON body (not form-encoded) in signature
- Verify you're using correct webhook secret from dashboard
See HMAC Authentication for detailed debugging steps.
Rate Limiting
Problem: Error 1429 or 1453-1456 (Rate limit exceeded)
Solutions:
- Implement exponential backoff (see examples above)
- Cache transaction status queries instead of polling frequently
- Use webhooks instead of polling for status updates
- Contact support to discuss higher rate limits
Rate Limits:
- Payment Providers API: 1000 requests/minute per partner
- Banks API: 200 requests/minute per bank
Transaction Processing
Problem: Error 3003 (Duplicate transaction reference)
Solutions:
- DO NOT create a new reference and retry
- Use
GET /debit-requests/:referenceto check existing transaction status - If status is
failed, you can retry with the same reference - Implement idempotency correctly - see Idempotency Guide
Problem: Error 3009 (Insufficient funds)
Solutions:
- This is a customer-side issue - notify customer to fund account
- Implement graceful error messaging in your UI
- Consider implementing retry logic that allows customer to retry after funding
Problem: Error 3004 (Unsupported currency)
Solutions:
- FLUID Network currently only supports GHS (Ghana)
- Verify currency is set to "GHS" in all requests
- See Currency Codes Reference
Connector/Bank Errors
Problem: Errors 2001, 2002, 2408, 2500, 2502
Solutions:
- These are typically transient - implement retry with exponential backoff
- If persistent (>5 minutes), contact support with transaction ID
- Consider implementing fallback notification to customer
Webhook Issues
Problem: Error 4001 (Webhook delivery failed)
Solutions:
- Ensure webhook endpoint is publicly accessible (not localhost)
- Endpoint must return HTTP 200 status code
- Respond within 30 seconds (queue long-running tasks)
- Check firewall/security rules aren't blocking FLUID IPs
Problem: Error 4401 (Invalid webhook signature)
Solutions:
- Verify signature using webhook secret from dashboard
- Use raw request body (don't parse before verifying)
- Check you're using correct signature algorithm (HMAC-SHA256)
- See Signature Verification
Best Practices
1. Always Use Structured Error Handling
✅ Correct approach: Handle errors by checking the numeric error code from the API response. Error codes are stable and won't change between API versions.
❌ Incorrect approach: Don't parse or match error message text strings. Error messages may be updated for clarity without notice, which would break string-based error handling.
Why: Error codes provide a stable contract for error handling, while message text is meant for human readability and may evolve over time.
2. Implement Retry Logic for Transient Errors
Retry these error codes with exponential backoff:
- 2001-2999: Connector/integration errors
- 1429: Rate limiting errors
- 1503: Service unavailable
3. Log Error Details for Debugging
Always log:
- Error code
- Error message
- Transaction ID (if applicable)
- Request ID (from
X-Request-IDresponse header) - Timestamp
4. Use Webhooks Instead of Polling
Polling for transaction status can cause rate limiting. Use webhooks for real-time updates:
- Subscribe to
debit_request.completedanddebit_request.failedevents - See Webhooks Overview
5. Implement Idempotency Correctly
- Use same reference for retries of the same payment
- Check transaction status before retrying on errors
- See Idempotency Guide
Support
If you encounter errors not covered in this guide:
- Review Error Handling Guide for patterns
- Contact support with:
- Error code
- Transaction ID or Reference
- Request ID (from
X-Request-IDheader) - Timestamp of occurrence
Related Documentation
- Error Handling Guide - Error handling patterns and strategies
- Status Codes Reference - Transaction status definitions
- Rate Limiting Guide - Rate limit details and best practices
- Idempotency Guide - Handling duplicate requests safely
- HMAC Authentication - HMAC signature implementation
- Webhooks Overview - Webhook integration guide