provider_verification_error
hooksentinel error provider_verification_error — a provider-specific check beyond the generic signature/timestamp validation failed.
Summary
| Field | Value |
|---|---|
| Code | provider_verification_error |
| HTTP status | 400 |
| Retryable | No |
What caused it
Some providers require verification steps beyond a straightforward "compute an HMAC and compare it" that don't fit any of the other, more specific error codes. provider_verification_error covers those provider-adapter-specific checks. Concretely:
- Discord's interaction handshake. Discord requires your endpoint to respond correctly to a
PINGinteraction type as part of registering the endpoint; a malformed or missing response to that handshake surfaces here rather than as a generic signature failure, since the Ed25519 signature itself may have verified fine. - Twilio's URL mismatch. Twilio signs over the exact URL your webhook is registered at, passed explicitly via the
urlconfig option. If that URL doesn't match what's registered in the Twilio console (wrong protocol, trailing slash, or a proxy rewriting the path before your app sees it), Twilio's own signature check fails in a way that's distinguishable from a generic bad-secretinvalid_signatureat the adapter level. - A provider adapter configuration that makes verification impossible to even attempt — e.g. a required config field left empty — as opposed to
invalid_signature, which means verification ran and produced a mismatch.
The fix
For Discord, make sure hooksentinel's Discord adapter is the thing responding to the interaction endpoint — it handles the PING handshake automatically. If you've wrapped or proxied the route in a way that intercepts the response before it reaches Discord's verification step during setup, the handshake will fail even though your public key is configured correctly.
For Twilio, double-check the url you pass matches the exact URL in the Twilio console, byte for byte, including protocol and trailing slash:
import { twilio } from '@hooksentinel/core';
twilio({
authToken: process.env.TWILIO_AUTH_TOKEN!,
url: 'https://api.example.com/webhooks/twilio', // must match the Twilio console exactly
});If your app sits behind a reverse proxy that rewrites the path (e.g. stripping an /api prefix, or terminating TLS such that your app sees http:// internally while Twilio signed against https://), pass the externally-visible URL Twilio actually used — not whatever your app sees req.url as internally.
For any provider, log the full error to see which specific check failed:
onError: async (error, ctx) => {
if (error.code === 'provider_verification_error') {
logger.warn('provider verification failed', {
provider: ctx.provider,
eventId: ctx.eventId,
message: error.message,
});
}
},error.message for this code names the specific check that failed, since the underlying cause varies by provider more than for the other, more generic error codes.
Last updated on