twilio-13221TwiliohighInvalid TwiML Verb
TwiML document contains an invalid or misspelled verb element that Twilio does not recognize.
What this error means
Root causes
Misspelled TwiML verb element name (e.g., <Saay>, <DIal>, <Recod>)
Common
Incorrect capitalization — TwiML verbs are case-sensitive and must be PascalCase
Common
Use of deprecated or removed TwiML verbs from older API versions
Occasional
Template rendering engine injecting unexpected XML elements or whitespace nodes
Occasional
Copy-paste error importing XML from a non-TwiML context into call logic
Occasional
Dynamic TwiML generation code producing invalid element names based on variable interpolation
Rare
How to fix it
- 1
Inspect the TwiML document returned by your webhook
Capture the exact TwiML your webhook is returning by testing it directly with curl or Postman. Examine the raw XML to identify which element Twilio flagged as invalid. The Twilio Debugger in the Console will show the exact element name that caused the error.
- 2
Cross-reference against the official TwiML verb list
Verify every element in your TwiML document against the official Twilio TwiML verb reference at https://www.twilio.com/docs/voice/twiml. The allowed top-level voice verbs are: <Connect>, <Dial>, <Echo>, <Enqueue>, <Gather>, <Hangup>, <Leave>, <Pause>, <Play>, <Queue>, <Record>, <Redirect>, <Reject>, <Say>, <Sms>, <Stream>. Any other element is invalid.
- 3
Fix capitalization errors
Ensure all TwiML verbs use exact PascalCase as documented. Common capitalization mistakes include <say> instead of <Say>, <DIAL> instead of <Dial>, and <gather> instead of <Gather>. XML is case-sensitive, so these will all trigger 13221.
- 4
Use Twilio's TwiML helper libraries to generate TwiML
Instead of hand-writing XML strings, use the official Twilio helper library for your language. These libraries generate syntactically correct TwiML and eliminate typos entirely.
// Node.js — use twilio helper library to build TwiML safely const twilio = require('twilio'); app.post('/webhook', (req, res) => { const twiml = new twilio.twiml.VoiceResponse(); twiml.say({ voice: 'Polly.Joanna' }, 'Hello, this is a valid TwiML response.'); twiml.dial().number('+15551234567'); res.type('text/xml'); res.send(twiml.toString()); }); - 5
Validate TwiML before deploying
Use Twilio's TwiML Validator tool at https://www.twilio.com/console/voice/twiml to paste and validate your TwiML document before putting it into production. Alternatively, use an XML schema validator with Twilio's published TwiML XSD.
- 6
Add TwiML output logging in your webhook handler
Log every TwiML response your webhook generates before sending it. This makes it easy to reproduce and debug problems without having to trigger a live call. Include the full XML string in your application logs at DEBUG level.
- 7
Review template rendering logic for dynamic verb generation
If you generate TwiML verb names dynamically from variables (e.g., mapping a config value to a verb string), add validation to ensure only whitelisted verb names are used. Reject or fallback gracefully if an unknown verb name is encountered.
const VALID_TWIML_VERBS = new Set([ 'Connect', 'Dial', 'Echo', 'Enqueue', 'Gather', 'Hangup', 'Leave', 'Pause', 'Play', 'Queue', 'Record', 'Redirect', 'Reject', 'Say', 'Sms', 'Stream' ]); function buildVerb(verbName, content) { if (!VALID_TWIML_VERBS.has(verbName)) { throw new Error(`Invalid TwiML verb: ${verbName}`); } return `<${verbName}>${content}</${verbName}>`; } - 8
Check Twilio Debugger for the exact offending element
Open the Twilio Console, navigate to Monitor > Debugger, and find the error event for 13221. The debugger shows the exact XML element name that Twilio rejected, as well as the full TwiML document it received. This is the fastest way to pinpoint which verb is malformed.
Prevention
Prevent 13221 errors by always using official Twilio helper libraries (twilio-node, twilio-python, twilio-java, etc.) to construct TwiML programmatically rather than building raw XML strings. These libraries enforce correct verb names and attributes at the code level. Integrate TwiML validation into your CI/CD pipeline using unit tests that assert your webhook responses parse as valid TwiML. Log all generated TwiML in development and staging environments so regressions are caught before production deployment. When adding new call flows, reference the official TwiML documentation and test the document in Twilio's validator tool before releasing.
Debugging this right now?
Sherlock diagnoses twilio-13221 automatically. Just ask in Slack and get an instant root-cause analysis.
Add to Slack — Free