twilio-13221Twiliohigh

Invalid TwiML Verb

TwiML document contains an invalid or misspelled verb element that Twilio does not recognize.

What this error means

Error 13221 occurs when Twilio parses your TwiML document and encounters an XML element that is not a valid TwiML verb. TwiML has a specific, finite set of allowed verbs (such as <Say>, <Dial>, <Gather>, <Play>, <Record>, <Redirect>, <Reject>, <Pause>, <Hangup>, <Enqueue>, <Leave>, <Sms>, <Message>, <Stream>). Any element outside this list — whether due to a typo, incorrect capitalization, or use of custom XML tags — will cause Twilio to throw error 13221 and halt execution of the TwiML document. Call flows that depend on the malformed TwiML will fail, often resulting in calls being dropped or callers hearing nothing.

Root causes

high

Misspelled TwiML verb element name (e.g., <Saay>, <DIal>, <Recod>)

Common

high

Incorrect capitalization — TwiML verbs are case-sensitive and must be PascalCase

Common

medium

Use of deprecated or removed TwiML verbs from older API versions

Occasional

medium

Template rendering engine injecting unexpected XML elements or whitespace nodes

Occasional

high

Copy-paste error importing XML from a non-TwiML context into call logic

Occasional

high

Dynamic TwiML generation code producing invalid element names based on variable interpolation

Rare

How to fix it

  1. 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. 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. 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. 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. 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. 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. 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. 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