Skip to content

Field notes

Twilio fix guides

Most Twilio failures are a setting, not a bug. A number is still pointing at the demo TwiML URL, a campaign never finished registering, a webhook has no fallback. None of it raises an exception in your code — the message simply does not arrive. Each note here explains one such problem and gives you a script that finds it through the API.

Read-only keyPython and Node.jsTests included
Browse all 117 scripts on GitHub Download them all as a zip Field guide PDF (117 fixes, 200 KB) Follow @allanninal Every fix on this page has a tested Python and Node.js script in the repo. Free, and MIT as stated in its README.
Why these scripts never write

A script here holds a credential to an account that can send messages and charge you for them. So these read, they tell you exactly what is wrong, and they print the repair: the resource, the field, the value. You run it.

Give them a Twilio API Key with read access rather than the account auth token. If a read-only key leaks, somebody learns your phone numbers; if the auth token leaks, somebody sends from them.

Twilio

TwilioDiagnostic

A phone number still points at Twilio's demo TwiML

Callers hear the Twilio demo greeting instead of your app. The webhook answers 200, every call is marked completed, and error monitoring never sees it.

TwilioDiagnostic

Inbound SMS disappears into a number with no sms_url

The Messaging Service has an inbound URL and it is being ignored. Deferring to the sender's webhook means a blank sms_url on the number drops every reply.

TwilioDiagnostic

A Messaging Service with no A2P campaign fails US sends

us_app_to_person_registered is false, so every US 10DLC send returns 30034. The service accepts numbers and API calls happily; only the message fails.

TwilioDiagnostic

A number with no fallback URL drops the call when yours 500s

Twilio calls the fallback URL only when the primary handler errors. With none configured, one 11200 during a deploy is a lost customer call.

TwilioDiagnostic

13224: Twilio refuses the number your Dial verb asked for

The leg never rings and the parent call carries on to the action URL. The destination is national format, a premium range, or a number that does not exist.

TwilioDiagnostic

Answering machine detection is routing humans to voicemail

answered_by comes back machine_start or unknown on calls a person picked up. The connect rate falls and every call still reads as completed.

TwilioDiagnostic

A recording row says absent and there is no media behind it

The Recording resource exists, status is absent, error_code is set and the media URL 404s. The call completed normally, so nothing else looks wrong.

TwilioDiagnostic

21215: dialing permissions block a country you sell into

Calls to one country fail with 21215 or 13227 while the identical code works at home. Subaccounts fail on their own when inheritance is off.

TwilioDiagnostic

High risk dialing prefixes left open to toll fraud

Nothing fails. The toll-fraud and special-service ranges stay callable on an upgraded account, and one compromised endpoint runs five figures overnight.

TwilioDiagnostic

Verify runs with lookup_enabled false, so landlines are billed

skip_sms_to_landlines needs lookup_enabled and it is off by default. Verify sends into landlines at full price and 60205 never reaches your logs.

TwilioDiagnostic

An invalid or uncovered number: 21211 on send, 60600 on Lookup

Twilio does no fuzzy parsing. A national-format number stored years ago fails with 21211, and a range no carrier was ever assigned comes back 60600.

TwilioDiagnostic

11200 on the TwiML fetch: the call fails, not just a receipt

Anything outside 2xx is a retrieval failure. On an inbound handler that is a dropped call or a lost message, not a delivery receipt that went missing.

TwilioDiagnostic

12200: TwiML that parses, fails the schema, and is skipped

The document is well formed, so 12100 never fires. The verb is miscased, the schema rejects it, and Twilio logs the whole thing at warning.

TwilioDiagnostic

A rejected WhatsApp content template blocks every send

whatsapp.status is rejected and 63040 comes back on every send. Outside the 24 hour window an approved template is the only thing that will deliver.

TwilioDiagnostic

Carrier filtering drops your SMS silently with error 30007

Messages go undelivered with error_code 30007. Nothing arrives, you are billed anyway, and the Messages list has no error filter to find them with.

TwilioDiagnostic

Sends to recipients who texted STOP bounce with 21610

Twilio remembers the opt-out and your database does not, so every send to that number is rejected with 21610 and the compliance record keeps growing.

TwilioDiagnostic

SMS to a landline fails with 30006 and retrying never helps

Error 30006 and 21614 mean the destination cannot receive SMS at all. The retry loop bills you forever; Lookup line type is what settles the argument.

TwilioDiagnostic

Messages stay queued or accepted and never reach a final state

Status sits at queued or accepted for hours with no error_code. Part of it is throughput starvation, part is a scheduled send, and sent is not a failure.

TwilioDiagnostic

A2p campaign is FAILED and errors[] names the rejected field

campaign_status is FAILED and every US send returns 30034. The errors[] array names the exact attribute that was rejected, and nobody reads it.

TwilioDiagnostic

An A2P brand stuck at FAILED blocks every campaign under it

BrandRegistration.status is FAILED, so no campaign can attach and every US send is 30034. The reason is in errors[], not in the deprecated prose fields.

TwilioDiagnostic

An a2p campaign parked at IN_PROGRESS is not a live campaign

campaign_status sits at IN_PROGRESS for weeks, campaign_id is null, and the launch ships anyway. Nothing errors, and every US send returns 30034.

TwilioDiagnostic

An unverified toll-free number is blocked, not throttled

Every US and CA message from an unverified +1 8XX number fails 30032, and you are billed for the attempts. Pending review is a blocked state too.

TwilioDiagnostic

Status callback failures with 11200 leave delivery state blind

Twilio delivered the message and your database still says queued. The 11200 alerts name the failing endpoint; the Messages list is the state that is true.

TwilioDiagnostic

Twilio cannot open a TCP connection to your webhook (11205)

11205 means the handshake never completed, so your access log is empty. Whether that is a firewall, a dead host or a private address is one read away.

TwilioDiagnostic

An expired webhook certificate fails every request with 11236

11236 arrives at a sharp timestamp boundary and every number on that hostname breaks at once. Alerts are kept 30 days, which bounds what you can see.

TwilioDiagnostic

A webhook hostname with no public DNS record fails with 11210

11210 is a name Twilio cannot resolve from the public internet: an internal zone, a dead developer tunnel, or a record that was never published.

TwilioDiagnostic

A number with an Application SID ignores its own voice_url

When voice_application_sid is set it wins outright and voice_url is ignored, so every edit to the number changes nothing and calls keep hitting an old app.

TwilioDiagnostic

An empty sender pool fails every send with error 21704

The Messaging Service exists and looks configured, but no sender was ever added, so Twilio has no From to pick and rejects before any carrier hop.

TwilioDiagnostic

A voice-only From number fails every SMS with error 21606

21606 says the From is not a message-capable Twilio number for this account. Usually it is voice-only, on another subaccount, or not in E.164 format.

TwilioDiagnostic

No status callback means delivery failures never reach you

Messages.create returns queued and your database records a success. Terminal status and error_code arrive only by status callback or Event Streams.

TwilioDiagnostic

SMS Pumping Protection blocks legitimate OTPs with 30450

Sends to one country start failing with error_code 30450, then recover on their own. The Messages list has no error filter, so nothing catches the window.

TwilioDiagnostic

Error 21617: the rendered message body exceeds 1600 chars

Error 21617 rejects the send before a Message row exists, so it never appears in the Messages list. Monitor Alerts is the only read-only path to it.

TwilioDiagnostic

One smart quote triples your segment count and your bill

One smart quote forces UCS-2 for the whole body: 70 characters a segment instead of 160. Nothing errors, num_segments triples and so does the bill.

TwilioDiagnostic

Queue overflow 30001: a send loop outruns one long code

Bulk sends through one long code fail with error_code 30001. The queue holds about ten hours of segments at 1 MPS, and the producer outruns it.

TwilioDiagnostic

Phone numbers with no traffic still bill every month

Idle Twilio numbers rent forever. Compare each number's inbound and outbound activity against its monthly rate to get a figure somebody can act on.

TwilioDiagnostic

A trial account rejects multi-segment messages with 30044

Short test messages send. Real templates fail with 30044 because a trial account caps length, and one emoji halves the per-segment budget to 70 characters.

TwilioDiagnostic

Outbound messaging is off, so every send fails with 30037

One subaccount returns 30037 on every send while the others are fine. Read Accounts.json for status, attribute the failures by account_sid, and find it.

TwilioDiagnostic

Recycled numbers send OTPs to whoever owns them now

Carriers reissue deactivated numbers. Pull Twilio's Deactivations feed, reconcile it against your contact list, and find the codes going to a stranger.

TwilioDiagnostic

Verify conversion collapses in one country: SMS pumping

Verify spend jumps, mostly to one country, and almost none of those codes are ever entered. No error code: the sends succeed and are billed.

TwilioDiagnostic

A Verify Service with zero rate limits configured

Verify's built-in protection is per phone number only. With no Service Rate Limits, one script rotating destinations from one IP is entirely unthrottled.

TwilioDiagnostic

Fraud Guard blocked the prefix, so real users get 60410

One country cannot sign up for twelve hours. Fraud Guard saw pumping-shaped traffic on a prefix and blocked it, and legitimate users share that prefix.

TwilioDiagnostic

Verify sends SMS to a landline: 60205, or just silence

A slice of users never receive their code. The destination is a landline or fixed VoIP range that cannot receive SMS, and Verify bills the attempt anyway.

TwilioDiagnostic

A SIP trunk with no disaster recovery URL loses every call

disaster_recovery_url is empty by default. Nothing reports it until the PBX goes down, and then inbound calls to the trunk are dropped with no fallback.

TwilioDiagnostic

A SIP Domain with no auth_type accepts no traffic at all

A SIP Domain routes traffic only when auth_type is IP_ACL or CREDENTIAL_LIST. Left undefined, every INVITE is refused before your voice_url is fetched.

TwilioDiagnostic

Dial rejected with 13214 on a passed-through caller ID

A Dial with no explicit callerId forwards whatever the inbound leg carried. When a carrier delivers a malformed From, the outbound leg is rejected as 13214.

TwilioDiagnostic

A rising share of outbound calls end in status failed

No single error code explains it. The Calls resource is the only place a failure rate rather than an event is visible, and only if you fetch the denominator.

TwilioDiagnostic

No Usage Trigger, so overspend runs with nothing watching

Usage Triggers are the only server-side spend alarm Twilio has, and an account starts with none. Find that, and the dead triggers, before the invoice does.

TwilioDiagnostic

No API keys exist, so the auth token is the credential

The auth token authenticates every service and signs every webhook, so rotating it is account-wide and instant. Find out whether anything still holds it.

TwilioDiagnostic

Years-old API keys are still live with nobody owning them

API keys never expire and carry no last-used timestamp. Find the nameless ones, and know what deleting one takes down before you delete it.

TwilioDiagnostic

An approved regulatory bundle is counting down to expiry

The bundle proving your address to a regulator has a valid_until. It passes, the bundle is auto-rejected, and the numbers attached to it go non-compliant.

TwilioDiagnostic

Signature validation rejects Twilio with 403 behind a proxy

It worked on the laptop and 403s in production. The signature covers the URL Twilio called, not the one your proxy handed the app.

TwilioDiagnostic

A TwiML response with the wrong Content-Type fails with 12300

The body is valid TwiML and Twilio never parses it. 12300 is decided on the response header, and a missing header shows up as 502 instead.

TwilioDiagnostic

TwiML that is not well-formed XML fails with 12100

12100 is an XML parser refusing your document. Usually one blank line before the declaration. The bytes Twilio received are one fetch away.

TwilioDiagnostic

A TwiML response over 64 kB drops the call with 11750

11750 is usually not a big TwiML document. It is an HTML stack trace returned where TwiML was expected, and the giveaway is in the body.

TwilioDiagnostic

A Studio Flow left in draft, so your edits are live nowhere

Studio keeps a published revision and a draft. The Console shows the draft; a number pointed at the Flow runs the published one. Your change is live nowhere.

TwilioDiagnostic

A published Studio Flow that no phone number points at

Publishing a Flow does not attach it to anything. The Flow has zero executions while inbound calls and SMS still hit the old webhook, or Twilio's demo TwiML.

TwilioDiagnostic

A conversation webhook with no URL fails every event: 50369

Error 50369 says the conversation webhook URL was not provided. The webhook exists, it is attached, and configuration.url is empty, so no event ever leaves.

TwilioDiagnostic

A failed Event Streams sink drops events and nothing says so

A sink whose status is failed has stopped delivering. Messages and calls carry on as before, downstream analytics quietly stop, and no error code is raised.

TwilioDiagnostic

SMS Geo Permissions are off for the destination country

Error 21408 on every message to one country. There is no API that reads this setting, so the traffic is the only evidence you can get.

TwilioDiagnostic

An alphanumeric sender ID is unregistered where you send

30040 and 30041 arrive only from the destination carrier, so the API returned 201 and the sender looks fine. Find which sender IDs die in which country.

TwilioDiagnostic

US and Canadian numbers with no registered E911 address

There is no error until somebody dials 911. Then the call reaches a national centre that has to ask where you are, and the per-call fee arrives later.

TwilioDiagnostic

A short code used outside its own country fails 21612

Short codes are licensed nationally. A pool that mixes one with long codes will hand it an international message, and that send is rejected 21612 or 21606.

TwilioDiagnostic

An A2P brand parked at PENDING for weeks with no callback

The brand never failed and never approved. status is PENDING or IN_REVIEW, tcr_id is null, and the status callback that was supposed to tell you was missed.

TwilioDiagnostic

A SUSPENDED brand suspends every campaign underneath it

Traffic that worked yesterday returns 30033 and the campaign reads SUSPENDED. The cause is one level up: the brand was suspended and the cascade is silent.

TwilioDiagnostic

Brand failed 30799: the EIN does not match the legal name

The commonest Standard brand rejection. TCR checks the EIN against public tax records and needs an exact match, so a DBA or an old address fails it.

TwilioDiagnostic

An approved brand with no trust score is throttled to the floor

The brand is APPROVED, campaigns are still rejected for AT&T and throughput sits at the lowest tier. brand_score is null because secondary vetting never ran.

TwilioDiagnostic

Error 11220: the TLS handshake with your webhook never completes

11220 is a refusal during negotiation, before any certificate is presented. Browsers still load the URL because they offer things Twilio's client does not.

TwilioDiagnostic

Error 11237: your webhook sends a chain Twilio cannot verify

A missing intermediate or a private CA leaves Twilio with no path to a trusted root. Browsers hide the fault by fetching the part your server left out.

TwilioDiagnostic

Error 11206: Twilio cannot parse your webhook's HTTP response

Your server logs a 200 and Twilio logs a protocol violation. What broke the parse is in response_headers, which only the single-alert fetch returns.

TwilioDiagnostic

Number webhooks on http, a private address or a dev tunnel

Three faults in one field: cleartext signatures, an address Twilio can never reach, and a tunnel that dies with the laptop. All visible in configuration.

TwilioDiagnostic

The balance is one busy hour from a 20005 suspension

Twilio is prepay: at zero the account is suspended, not throttled. Compare Balance.json against your real daily burn and count the days of runway.

TwilioDiagnostic

A suspended subaccount, so one tenant's traffic 20005s

Twilio notifies nobody when a subaccount is suspended. List Accounts.json by status with parent credentials and find the tenant that quietly stopped.

TwilioDiagnostic

REST concurrency exhausted, so bursts come back 20429

Twilio caps concurrent REST requests per account and the ceiling is in no response body. Sample Twilio-Concurrent-Requests at peak, before it bites.

TwilioDiagnostic

Recordings billed for storage until something deletes them

Twilio stores call recordings forever and bills per stored minute. Read the accumulated recordings spend and the oldest file, not the number of files.

TwilioDiagnostic

Error 30003 is a handset that is off, not a dead number

30003 is transient: retry once and most of it delivers. But a fifth of one sender's traffic failing this way is a carrier block wearing a handset error code.

TwilioDiagnostic

Error 30005 is permanent: the carrier has no such number

30005 means the number does not exist on the carrier. Retrying is billed and can never work, so the finding is which contacts to delete rather than requeue.

TwilioDiagnostic

Error 30036: messages expire in the queue before they send

A ValidityPeriod shorter than the real queue wait kills messages before their turn. 30045 and 30012 are the request-time cousins with a different fix.

TwilioDiagnostic

Error 30019: the MMS is too big for the carrier, not for Twilio

Twilio accepts 5 MB and carriers stop between 300 KB and 3.5 MB, so the same image delivers to one recipient and fails for the next with error 30019.

TwilioDiagnostic

A suspended campaign returns 30033 and the sends keep coming

Every US message fails with 30033 and the producer has not been told. The Messages list dates the suspension and shows what your code did after it.

TwilioDiagnostic

30022 when sends outrun the throughput the carrier assigned

Intermittent 30022 at peak and nothing wrong at 3am. Compare your busiest minute against rate_limits on the campaign before asking for more throughput.

TwilioDiagnostic

A 10DLC number outside the sender pool is never registered

The brand is APPROVED and the campaign VERIFIED, and this number still 30034s. A2P registration attaches through the pool, and this number is not in one.

TwilioDiagnostic

30035 and 30024 are a clock, not a configuration mistake

A new sender fails for up to 24 hours while carrier routing catches up. Removing and re-adding the number restarts the clock instead of ending it.

TwilioDiagnostic

A Verify Service issuing four-digit codes to production

Four digits is ten thousand codes and each verification allows five checks. No error code will ever mention it, and nobody has looked at the field since.

TwilioDiagnostic

60202: a verification that burned all five check attempts

The code is right and the check still fails. A handler that fires on every keystroke spends the five-attempt budget before the user has finished typing.

TwilioDiagnostic

60203: a resend button with no cooldown burns five sends

Verify allows five sends per verification. A resend with no cooldown, or a retry that treats slow SMS as failure, drains them in seconds and bills each one.

TwilioDiagnostic

OTP codes sent without the do-not-share warning line

do_not_share_warning_enabled is off by default, so the SMS is a bare code. A custom default template can drop the line even when the flag is on.

TwilioDiagnostic

Dial fails with 32009 because the SIP endpoint is not there

32009 means the user you dialled holds no registration on the domain. A dropped REGISTER refresh and a username that never matched look identical.

TwilioDiagnostic

32011: Twilio cannot reach your SIP infrastructure

Twilio got no answer, a SIP 5xx, or something it could not parse from your origination URI. Redundancy that all resolves to one host is not redundancy.

TwilioDiagnostic

A trunk sheds calls at its CPS limit and the average hides it

32001 is a ceiling hit inside one second. Failures cluster in the first moments of a batch and disappear into any hourly rate you compute afterwards.

TwilioDiagnostic

A carrier blocks your caller ID and 32017 is the only notice

32017 is a terminating carrier refusing a number on reputation. The score is built from answer rate and call duration, both of which you can read.

TwilioDiagnostic

A rejected regulatory bundle blocks every number purchase

The bundle failed review, not the clock. Until somebody reads its item assignments and resubmits it, no number can be bought in that country.

TwilioDiagnostic

A bundle is noncompliant on a field only Evaluations names

The bundle will not submit and the status says nothing useful. The per-requirement breakdown naming the exact failing field is in a subresource.

TwilioDiagnostic

One rejected Trust Hub profile fails brands and toll-free

A brand rejection and a toll-free rejection that make no sense together usually share one cause: the Customer Profile both of them hang off.

TwilioDiagnostic

A rejected toll-free verification is fixable or it is not

TWILIO_REJECTED carries a coded reason and an edit window. Correcting the named fields works for some codes and can never work for others.

TwilioDiagnostic

The account itself is suspended, so every send fails with 20005

Status on the top-level account, not on a subaccount. One GET answers it, and the 30002s on the queued backlog say when it started.

TwilioDiagnostic

A production integration is still running on a trial account

Trial accounts reach three lifetime-verified numbers and prefix every message body. Count how much real traffic is already aimed at one.

TwilioDiagnostic

The trial account's three verified numbers are spent

A teammate's phone gets 21608 while the first developer's still works. The trial verification quota is three numbers for the account's lifetime.

TwilioDiagnostic

20003 on a read key: dead credential or a real boundary

A read-only key gets 20003 on Keys and Accounts by design. Tell that boundary apart from a wrong SID, a stale key, or a suspended account.

TwilioDiagnostic

A Studio Flow whose definition is invalid, so widgets never run

The Console draws the canvas and valid is false. A transition to a deleted widget leaves the definition uncompilable, and executions stop at the break.

TwilioDiagnostic

Conversations webhooks fire for nothing when filters are empty

post_webhook_url is set and correct and nothing ever arrives. Conversations delivers only the events named in filters, and an empty list names none of them.

TwilioDiagnostic

Five conversation webhooks is the cap, and the sixth is rejected

Error 50361 lands on whichever integration deployed last. The conversation already holds five webhooks, and two of them often point at the same URL.

TwilioDiagnostic

A Sync webhook rejected as invalid, or never called at all

Error 54051 is the loud half. The quiet half is webhooks_from_rest_enabled, off by default, so every change your own server makes over REST calls nothing.

TwilioDiagnostic

An SMS number that belongs to no Messaging Service

No error code, just unpooled sending: no sticky sender, no geomatch, no long code failover, and A2P registration that attaches through a pool.

TwilioDiagnostic

Error 21703: the pool has senders but none reach the To

Sender selection needs a pool member matching the destination country and message type. A pool with no US number fails every US send with 21703.

TwilioDiagnostic

Two toll-free numbers in one sender pool get both blocked

Carriers read several toll-free senders in one Messaging Service as snowshoeing and block them. Twilio's guidance is one toll-free number per service.

TwilioDiagnostic

A ten hour validity period delivers passcodes nobody wants

validity_period defaults to 36,000 seconds, so a queued passcode can wait ten hours and then arrive, after the user gave up and requested three more.

TwilioDiagnostic

Error 14107: an auto-reply loop trips the SMS rate limit

Twilio caps outbound at 30 messages between the same two numbers in 30 seconds. The limit is the symptom; a handler answering its own answer is the bug.

TwilioDiagnostic

Numbers still pinned to the 2008-08-01 API version

A number carries its own api_version, fixed when it was bought. A 2008 pin serves the old schema forever, without the fields the documentation promises.

TwilioDiagnostic

Programmable Chat is still in use past its end of life

Nothing breaks on a deprecation date, so the only signal is that you are still calling it. Count the Chat services, then find out what still depends on them.

TwilioDiagnostic

Notify services still on the account after Notify's EOL

Notify reached end of life and push stopped arriving, with no error anywhere. The services still exist in the API. The question is what is still bound to them.

TwilioDiagnostic

Call recordings stored without encryption at rest

Voice Recording Encryption is opt-in and not retroactive. Read encryption_details across the sample to learn when it was on and what is still in the clear.

TwilioDiagnostic

Nothing subscribes to error logs, so failures age out

Debugger alerts are kept 30 days and pushed nowhere unless something subscribes. Read the Event Streams subscriptions and what each one actually carries.

TwilioDiagnostic

A Sole Proprietor brand blocked by an OTP nobody answered

The brand never rises to VERIFIED because the owner never replied to the SMS passcode. The reply window is 24 hours and nothing tells you it closed.

TwilioDiagnostic

Extra numbers on a Sole Prop campaign never leave UNREGISTERED

A Sole Proprietor brand allows one campaign holding one number. Adding more never errors: the extras stay UNREGISTERED and 30034 arrives at random.

TwilioDiagnostic

T-Mobile caps daily segments per brand, not per campaign

Sends stop mid-afternoon with 30023 and resume at midnight Pacific. The ceiling belongs to the brand and every campaign under it shares one pool.

TwilioDiagnostic

A rejected toll-free record's edit window closes on a clock

edit_allowed is true and edit_expiration is days out. Miss it and the in-place correction is gone: only a fresh submission, at the back of the queue.

TwilioDiagnostic

A link shortening certificate expires and short links break

A bring-your-own certificate on a link-shortening domain has a fixed date_expires and is not renewed for you. 30131 warns, then 30120 breaks the sends.

Something not covered here?

These are the ones I keep hitting. If yours is broken in a way none of them describes, tell me on LinkedIn — it is usually how the next note gets written.