Skip to content

SMS delivery error codes: retry, remove the number, or fix your sender

published · September 27, 2026

Twilio, Sinch and MessageBird delivery error codes sorted by what to do next, and which of them a phone lookup can warn you about before you send.

An SMS delivery error code says why a message failed: the number is not an active line, the line cannot take text messages, the handset was out of reach at that moment, the recipient opted out, or your own sender was refused. Sinch 150 and MessageBird 1 mean the number is not an active line, so remove it; Twilio 30006, Sinch 152 and MessageBird 11 mean the line cannot take text messages, so reach the person another way; Twilio 30003 and MessageBird 29 mean the handset was off or out of reach, so retry later; Twilio 21610 and MessageBird 103 mean the recipient opted out, so stop; Twilio 30007 and 30034 mean your sender or your content was refused, and removing the number would only hide that. Twilio publishes no delivery code that proves a number is gone.

This guide sorts the codes of three SMS providers by what to do next, from each provider's own documentation, and says which failures a phone lookup can warn you about before you send. The code lists are the ones Spaw's status webhooks read, so every code in the tables below is recorded the way this page describes.

Five things a failed receipt can mean

What failed What to do Twilio Sinch MessageBird Can a lookup warn you first?
The number is not an active line, or its line is barred (permanent) Remove the number; for a barred line, stop until the recipient has the bar lifted none 150, 151 1 Only when the regulator's table shows no carrier holding the number's block, which the lookup refuses as invalid
The line cannot take SMS (not_sms_capable) Stop texting it and reach the person another way; for 30006 from a short code, Twilio suggests a long-code fallback first, and Sinch 154 can pass once the recipient is off the roaming network 30006 152, 154, 204, 212 10, 11, 21 A hint where the plan tells landlines from mobiles (line_type: fixed_line), which the plans of the US, Canada, several other +1 areas and Denmark do not; nothing for a plan, SIM or network without SMS
The recipient opted out (the opted_out outcome) Stop, and keep it stopped 21610 none in Spaw's table 103 Only from your own records (meta.opted_out)
The handset or its network, this time (transient) Retry later, and give up after repeats 4 codes: 30003, 30004, 30005, 30008 20 codes, such as 153, 159, 201 21 codes, such as 27, 28, 29 No: these describe the handset or its network when the message was sent, or are too vague to pin on the number (MessageBird marks 2 and 9, both about the handset's registration, permanent)
Your sender, content or sending rate (sender_side) Fix your registration, content or rate 12 codes, such as 30007, 30034, 30032, 30018 40 codes, such as 60, 62, 64, 310 11 codes, such as 104, 105, 110 No lookup of the recipient can; MessageBird 131, a destination its pumping guard forbids, is covered below

The words in brackets are the failure_class Spaw records for a failed delivery, and opted_out is recorded as an outcome of its own, never as a failure. The providers' own labels differ: Sinch and MessageBird mark most codes permanent or temporary ("intermediate" in MessageBird's table), and Twilio marks none. Spaw's classes answer a narrower question than the providers' labels do: is the failure about the number? A code the provider calls permanent because the sender is unregistered, such as MessageBird 104, is sender_side here, because the number is fine.

The codes that are about the number

Thirteen codes across the three providers say something about the recipient's number rather than the moment or the sender (MessageBird 131, a destination its pumping guard forbids, is kept with the sender-side codes, for the reason given further down). The descriptions paraphrase each provider's documentation: Twilio's error dictionary, Sinch's SMPP error codes, which Spaw reads from the code field of its delivery reports, and MessageBird's SMS API reference, all checked 27 September 2026.

Provider Code Provider's name Spaw records What the provider's documentation says Before sending
Twilio 30006 Landline or unreachable carrier not_sms_capable The destination is a landline, or the carrier cannot be reached from a short code A hint from fixed_line, where the plan tells landlines from mobiles
Twilio 21610 Attempt to send to unsubscribed recipient opted_out The recipient sent STOP or another opt-out keyword to your number, sender or Messaging Service; Twilio also lists a recently reassigned number as a cause Your own suppression list
Sinch 150 Unknown subscriber permanent The number is not active with the carrier Only if the regulator's table shows no holder for its block
Sinch 151 Call barred permanent The recipient's line is barred; Sinch says it might be best to stop sending to it for now, until the recipient has the bar lifted No
Sinch 152 Teleservice not provisioned not_sms_capable The line has no SMS subscription A hint from fixed_line, where the plan tells landlines from mobiles
Sinch 154 Facility not supported not_sms_capable SMS is not provisioned in the network the recipient is visiting, so it fails while they roam there and can pass once they are back on their home network No
Sinch 204 Facility not supported not_sms_capable SMS is not provisioned on the recipient's SIM No
Sinch 212 Device not short message equipped not_sms_capable The device cannot receive texts, such as a data-only SIM No
MessageBird 1 EC_UNKNOWN_SUBSCRIBER permanent The number is not associated with an active line Only if the regulator's table shows no holder for its block
MessageBird 10 EC_BEARERSERVICE_NOT_PROVISIONED not_sms_capable The subscriber has two numbers and this one is not enabled for SMS No
MessageBird 11 EC_TELESERVICE_NOT_PROVISIONED not_sms_capable Not a mobile, such as an IoT number, or a plan without SMS A hint from fixed_line, where the plan tells landlines from mobiles
MessageBird 21 EC_FACILITY_NOT_SUPPORTED not_sms_capable The receiving network does not support SMS No
MessageBird 103 EC_SUBSCRIBER_OPTEDOUT opted_out The recipient opted out; only an opt-in keyword such as START from them reverses it Your own suppression list

Two labels in the providers' tables read differently from Spaw's. Sinch marks 212 temporary, and MessageBird marks 10, 11 and 21 intermediate; Spaw keeps all four with the not-SMS-capable codes because each describes the line, the SIM or the network rather than the handset's state at that moment. MessageBird also files 21 under the status reason "received network error", which it calls temporary. Not-SMS-capable failures are never scored, so reading these four that way never counts them against the number.

Sinch has no opt-out row. Its SMPP table describes 255 and 257, both personal service barring, as an end user who opted out of messages, but gives 255 a second meaning for toll-free senders: a message the carrier blocked for spam filtering. Its 10DLC and toll-free error page (checked 27 September 2026) maps toll-free 255 to spam and only 257 to a STOP. Spaw's table reads neither, so a receipt carrying either is recorded as an unclassified failure. When you know the recipient opted out, report the number yourself with the outcome opted_out.

Twilio has no code that proves a number is gone

Spaw reads eighteen of Twilio's codes. The two about the number are in the table above; these are the other sixteen, and the four that can be about the handset are all read as transient, including 30005, whose name reads like a number that is gone.

Code Twilio's name Spaw records
30003 Unreachable destination handset transient
30004 Message blocked transient
30005 Unknown destination handset transient
30008 Unknown error transient
30001 Queue overflow sender_side
30002 Account suspended sender_side
30007 Message filtered sender_side
30017 Carrier network congestion sender_side
30018 Destination carrier requires sender ID pre-registration sender_side
30019 Content size exceeds carrier limit sender_side
30022 US A2P 10DLC - Rate Limits Exceeded sender_side
30023 US A2P 10DLC - Daily Message Cap Reached sender_side
30024 Numeric Sender ID Not Provisioned on Carrier sender_side
30027 US A2P 10DLC - T-Mobile Daily Message Limit Reached (deprecated; Twilio says it no longer generates it) sender_side
30032 Toll-Free Number Has Not Been Verified sender_side
30034 US A2P 10DLC - Message from an Unregistered Number sender_side

Twilio's page for 30005 says the destination number "is unknown and may no longer exist", and then lists a handset that is switched off or out of signal, a number that cannot receive SMS and a problem at the carrier among the possible causes. A code with four explanations, two of them passing, cannot justify removing a number on one sighting, so Spaw counts it with the other temporary failures: two of them with no delivery after them put the number on your suppression list. The same goes for 30004, whose causes include a blocked destination and filtering of your content.

Twilio documents two more codes about the number: 21211, an invalid To number, and 21614, "'To' number is not a valid mobile number". Both describe the To number of the API request that creates the message, and neither page says whether the error comes back on that request or on a status callback. Spaw's Twilio table does not read them, so a callback carrying either is recorded as an unclassified failure. 21614, which Twilio says may be a landline, is the one a fixed_line answer can hint at. For messages sent through a Messaging Service, 21610 arrives on the status callback: Twilio's Advanced Opt-Out documentation (a Messaging Service feature, checked 27 September 2026) says later messages to a recipient who opted out fail with 21610 asynchronously.

The twelve sender-side codes are about 10DLC and toll-free registration, sender IDs, content, sending rate, daily caps, carrier congestion and the account. Almost none of them says anything about the recipient: Twilio's 30024 page also lists a destination that recently ported, or is not provisioned for SMS, among its causes, which is one more reason Spaw never scores these codes against the number. The same failure meets the next person on your list until the registration, the content, the sending rate or the account is fixed, or until the day's cap resets (30023 resets at midnight Pacific time) or the carrier's congestion clears (30017, congestion in MMS traffic, which Twilio retries before it returns the code). Sinch's equivalents include 60, an originator whose campaign is not active, 62, a keyword that triggered a filter, and 64, a quota exceeded; its 10DLC and toll-free error page (checked 27 September 2026) maps the carriers' reasons to them. MessageBird's include 104 and 105, an unregistered sender or content, 130, which its surge guard returns when it sees a traffic-pumping pattern in your sending, and 131, which it returns when it has marked the destination itself as forbidden for suspected traffic pumping. Spaw files 131 as sender-side so that it is never scored against the number; one lookup cannot say a number is pumped, and what the default SMS policy lets through covers the rules that watch your own traffic for the pattern.

What a lookup can warn you about before you send

A block nobody holds. A number answers valid: false with the reason unassigned_block when the regulator's table lists its block as unassigned, whether the block was never handed out or was returned and is resting before reuse, or when its block is missing from a table that lists every assigned block and was synced within the last 45 days. The SMS policy blocks every invalid number, so a flow that checks ok_to_send never sends to it. The test number +1 202 555 0104 answers exactly that, ok_to_send: false with blocked_by: "invalid", and like every test number it costs nothing. This is the only part of the "remove the number" row a lookup can see: a number that was assigned and later disconnected usually sits in a block its carrier still holds, and passes. Which regulators publish such a table, and whether each is complete, is on the phone data sources page.

The live carrier-network check (hlr: true) is not enabled on the service: hlr_checked answers false and nothing extra is charged.

A fixed line, where the plan can tell. Where the numbering plan tells landlines from mobiles, the answer carries line_type: fixed_line from the plan; a London 020 number answers that way, and the page for the United Kingdom gives the digits its mobile numbers start with. It is a hint rather than a verdict, because some fixed lines are enabled for text. The default SMS policy blocks no line type; add fixed_line to blocked_line_types if you would rather not try. In the United States and Canada no real number answers fixed_line: the plan answers fixed_line_or_mobile, and the holder of the number's block can settle it only to mobile or voip, for the reasons in why US numbers cannot be split into mobile and landline. The same holds for Puerto Rico, the Dominican Republic, Jamaica, Guam, the Northern Mariana Islands, the US Virgin Islands and Denmark, and for part of India's plan; the other +1 areas, such as the Bahamas and Trinidad and Tobago, do answer fixed_line. A fixed_line_or_mobile answer predicts nothing about 30006.

Not toll-free. line_type: toll_free is not a sign that a number cannot take SMS. In the United States and Canada toll-free numbers can be enabled for texting, which is why Twilio has a code, 30032, for sending from one that has not been verified.

Not the plan, the SIM or the network. MessageBird 10, 11 and 21 and Sinch 154, 204 and 212 describe a subscriber's second number, a plan or SIM without SMS, a data-only device or a network that does not carry SMS. No public data shows any of these before a message is sent; only where 11 means the number is not a mobile at all can the fixed_line hint above flag a landline.

An opt-out, from your own list only. Once a recipient has opted out and you or your provider reported it, the number is on your suppression list with the reason opted_out, a single lookup answers meta.opted_out: true, and under the default policy that answer is ok_to_send: false with blocked_by: "opted_out". No public data says who opted out of whose messages. ok_to_send is a fraud and deliverability decision: it is not consent to message anyone and not a do-not-call scrub, and Spaw knows only the opt-outs you or your provider report to it.

A number that delivers but should not get the code. A number published on an SMS-receiving website takes messages, so the trouble with it is not a failed delivery and no error code flags it. Spaw can flag it before sending when one of the lists it syncs carries the number: the test number +1 202 555 0103 answers is_disposable: true and, under the default policy, blocked_by: "disposable". When one slips through, report it as abused, not as undelivered.

Sending the receipts back

Point each provider's status callback at https://spaw.co/api/v1/phone/feedback/{provider}/{key}, with twilio, sinch or messagebird as the provider and your account's feedback key, and the codes above are read from ErrorCode (Twilio), code (Sinch) or statusErrorCode (MessageBird). Spaw reads Sinch's SMS API delivery reports; Sinch's SMS API reference (checked 27 September 2026) says that API is available to its existing customers and that new customers send through its Conversation API, whose callbacks this webhook does not read. A MessageBird report without an error code falls back to its status reason, and unknown subscriber without the code stays transient, because MessageBird files eight codes under that reason and only 1 is read as permanent. The webhook reference lists the fields each provider sends. If your provider is not one of these, POST /api/v1/phone/feedback takes the same outcomes with a failure_class of your own reading.

What happens next depends on the class:

  • permanent, transient and unclassified failures count against the number. While the latest report about it in the last 90 days is a failure, your later lookups of the number carry reported_undelivered, +50. One permanent failure, or two of the others with no delivery or verification after them, puts it on your suppression list, which batch, bulk and monitored runs answer as suppressed, free. A later delivery or verified code takes it off.
  • not_sms_capable and sender_side failures are kept and never scored. They appear in undelivered_by_class on your feedback summary, which is where a jump in sender_side shows up as a registration or content problem rather than a list problem.
  • An opt-out is recorded as opted_out. It never scores, and it keeps the number on your suppression list until you remove the entry.

A code none of the tables lists is recorded as an unclassified failure, which counts against the number like a transient one: it adds reported_undelivered (+50) while it is the latest report, and two unclassified or transient failures with no delivery or verification after them put the number on your suppression list. Delivered, undelivered and opted-out reports only ever affect your own account's lookups; no other account reads them.

What to do next

Related

markdown version: /guides/sms-delivery-error-codes-explained.md

Verify addresses the same way

The Spaw API runs every check described here on each lookup, with an SMTP handshake that never sends mail. 10 free lookups a month, no card required.

Get your API key

More guides