Documentation Menu

Twilio Signature Validation Failed? Debug URL and Body Canonicalization

Problem Introduction

Twilio callbacks hit your endpoint, but signature checks fail.

Why It Happens

  • URL mismatch — your app sees internal URL but Twilio signed the public URL
  • Mutated request body/params by framework middleware
  • Wrong Auth Token — must be from Account Settings, not API Keys
  • HTTPS vs HTTP URL mismatch

Step-by-Step Fix

  1. 1Confirm the exact public URL Twilio POSTs to — including protocol, port, and path.
  2. 2Pass that exact URL (not your internal one) to the Twilio validator.
  3. 3Preserve POST params exactly as received — sorted alphabetically for validation.
  4. 4Use your Account Auth Token from console.twilio.com → Account Settings.
  5. 5Use the twilio npm package's validateRequest() utility instead of rolling your own.

Working Code

Copy-paste verified examples. Use the tab that matches your stack.

javascript
const twilio = require('twilio');

app.post('/webhooks/twilio', (req, res) => {
  const authToken  = process.env.TWILIO_AUTH_TOKEN;

  // CRITICAL: use the exact public URL Twilio sends to
  // If behind a proxy, set X-Forwarded-Proto and reconstruct:
  const publicUrl = process.env.TWILIO_WEBHOOK_URL;
  //  e.g. 'https://yourdomain.com/webhooks/twilio'

  const isValid = twilio.validateRequest(
    authToken,
    req.headers['x-twilio-signature'],
    publicUrl,
    req.body           // parsed POST params from express.urlencoded()
  );

  if (!isValid) {
    return res.status(401).type('text/xml').send('<Response><Reject/></Response>');
  }

  const from = req.body.From;
  const body = req.body.Body;
  console.log('SMS from', from, ':', body);

  // Respond with TwiML
  res.type('text/xml').send('<Response><Message>Got it!</Message></Response>');
});

Common Mistakes

  • Verifying against internal URL instead of public URL
  • Lowercasing or URL-encoding canonical inputs
  • Using a sub-account token when the webhook is on the main account

Debugging Workflow

Canonical URL check → payload capture → token verification → replay callback.

Preventive Best Practices

  • Keep one validation utility for all Twilio routes
  • Track signature failures by endpoint
  • Add regression tests for proxy scenarios

Works with webhooks and other async event systems (including AI callbacks). Instead of guessing, inspecting the exact payload and headers can help debug faster.

Try the free webhook tester

Was this page helpful?

Your feedback helps us improve the docs.