Troubleshooting common errors
Updated 25 September 20263 min read
On this page
This page covers the errors integrators hit most often, what actually causes them and the quickest way to fix each. Error codes are defined in Error format and codes.
entries_unbalanced
Symptom. POST /v1/transactions returns 422 with entries_unbalanced.
Cause. In at least one currency, the debits do not equal the credits. The message tells you the totals.
Fix.
- Sum the debits and credits per currency in your payload. They must match exactly.
- Check that amounts are integers in minor units.
12.50is wrong,1250is right. - For a multi-currency movement, balance each currency separately. A conversion is two balanced legs, not one unbalanced transaction. See Multi-currency ledgers.
insufficient_funds
Symptom. A payout or transaction returns 422 with insufficient_funds.
Cause. The account's available balance is lower than the outflow. Available is the posted balance minus pending outflows, so a balance that looks large can still be fully reserved by earlier payouts.
Fix. Read GET /v1/accounts/{id}/balances and compare available, not posted. Wait for pending transactions to post or void, or fund the account first. If a negative balance is legitimate for that account, create it with allow_overdraft=true. See Account balances.
resource_not_found for an id you just created
Symptom. GET /v1/ledgers/led_... returns 404 straight after you created it.
Cause. Almost always an environment mix-up. Sandbox ids do not exist in live, and the other way round. Check that the key prefix (ll_test_ or ll_live_) matches the base URL.
Fix. Use https://sandbox.api.ledgerline.dev/v1 with test keys and https://api.ledgerline.dev/v1 with live keys. If the base URL is right, check that your regional pin matches the organization's data region. See Data residency and retention.
api_key_invalid
Symptom. Every request returns 401.
Fix.
- The header must be exactly
Authorization: Bearer <key>. A missingBearerprefix is the usual culprit. - Remove trailing whitespace or newlines when you read the key from a file or environment variable.
- Make sure you copied the whole key. Keys are shown once, so if in doubt, roll it.
scope_missing
Symptom. 403 with scope_missing and the missing scope in param.
Fix. Create a new restricted key that includes the scope. Scopes cannot be added to an existing key. See Restricted keys and scopes.
idempotency_key_mismatch
Symptom. 422 when you retry a request.
Cause. You reused a key with different parameters. This usually means a key is generated per attempt in one place and per intent in another, or a field such as a timestamp changed between attempts.
Fix. Generate the key once per logical operation and send identical parameters on every retry. To make a deliberate change, use a new key. See Idempotency keys.
rate_limit_exceeded
Symptom. 429 responses, often in bursts after a deploy or a backfill.
Fix. Wait for the number of seconds in Retry-After, then resume with backoff. For backfills, throttle your producer to stay below 600 requests per minute per key, or use batch endpoints. See Rate limits.
counterparty_unverified
Symptom. A payout returns 422 with counterparty_unverified.
Fix. Verify the counterparty's bank account. Micro-deposit verification takes 1 to 2 business days, so start it as soon as you collect the account. See Counterparties and screening. In the sandbox, use the test account numbers listed in Sandbox to skip the wait.
limit_exceeded
Symptom. A payout is rejected with 422 and limit_exceeded.
Fix. The param field names the limit. Split the payment across rails or days, or move to a plan with higher limits. The limits per plan are in Limits and quotas.
fx_market_closed
Symptom. Requesting an FX quote returns 422.
Cause. Foreign exchange markets are closed from Friday 22:00 UTC to Sunday 22:00 UTC.
Fix. Retry after Sunday 22:00 UTC. Payouts in a currency you already hold are not affected. See FX quotes and conversions.
Webhook signature always fails
Verify against the raw request body, use the secret of the right endpoint and check for clock drift. The full checklist is in Verifying webhook signatures.
Still stuck
Collect the request_id from the error body and the time of the request, then open a ticket from this help centre. The request id lets us read the exact request and response.