Fix an empty sender pool (SENDER_POOL_EMPTY)
SENDER_POOL_EMPTY is a deterministic, pre-send rejection: your request
named a valid pool, Orbit looked up the pool, and found it has no members
to draw a sender from. The send never reaches a provider, so nothing to
retry — add a member to the pool (or route through a different pool) and
send again.
Symptoms
- The send request returns HTTP 422 with code
SENDER_POOL_EMPTY, and the response names the pool that was empty. - The dashboard Delivery Log shows no row for the message — the send was rejected before queueing, so there is nothing to deliver.
- The pool’s detail page prompts you to add a DID, and the senders list for the pool is empty.
GET /api/v1/messaging/sender-pools/{id}/preview) when the pool has no
members, so the symptom surfaces before you send real traffic if you
preview first.
Causes
The pool row exists and resolves — the failure is membership:- The pool’s
sender_didslist has no entries. Two ways a pool reaches that state: it never had members (created with an empty list and never filled, or the last member was removed), or the send carried a narrower recipient filter and none of the pool’s members were eligible, leaving zero candidates for that recipient. - A messaging service, campaign, or sender routing rule still points at the pool, so every send routed through it fails with the same code.
Fix: put a sender in the pool
Either fix the pool itself, or route the send elsewhere — tenant-owned controls only.- Add at least one member to the pool. A pool member can be an
E.164 DID, a numeric short code, or an alphanumeric sender ID —
update the pool with
PATCH /api/v1/messaging/sender-pools/{id}and setsender_dids, or add the sender in the dashboard’s pool editor. Make sure the sender is one your organisation actually owns:GET /api/v1/numberslists the DIDs on your organisation before you send. - Route through a pool that has members. Pass a different
sender_pool_idon the request, or repoint the wiring that led here — a messaging service’s default pool, a campaign, or a routing rule — at a non-empty pool. - Retry the send.
SENDER_POOL_EMPTYis rejected before any pick is made, so no selection state was written for the recipient — the retry routes cleanly, and the same idempotency key resubmits without a duplicate.
Distinguish it from the neighbouring codes
The telling difference:
SENDER_POOL_EMPTY is pool-level state (a good
pointer, an empty list), SENDER_POOL_NOT_FOUND is the pointer itself
(there is no pool), and NO_SENDER_CONFIGURED is organisation-level
state (no sender of any kind yet).
Example envelope
Related references
- Sender pools — create pools, add members, and understand selection strategies.
- Sender resolution — where the pool pick sits in the full precedence chain.
- Troubleshoot sender resolution and pool errors
— the three sibling codes (
SENDER_REQUIRED,SENDER_POOL_NOT_FOUND,NO_SENDER_CONFIGURED). - FAQ: Why did my send return
422 SENDER_POOL_EMPTY? — the one-line version of this page. - Error codes — the full sender error table.