yikart/AiToEarn · warning
ChannelWebhookInvalidVerifyToken
Error message
ChannelWebhookInvalidVerifyToken
What it means
Facebook webhook subscription verification (handleChallenge, called from handle for GET hub.mode=subscribe requests) responds 403 with ChannelWebhookInvalidVerifyToken when the hub.verify_token query parameter does not equal config.webhookVerifyToken or the challenge is missing. Meta sends this token once when you register the webhook URL; mismatch means Meta cannot complete subscription verification.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/facebook/facebook-webhook.provider.ts:66
}
response.status(200).send('EVENT_RECEIVED')
}
private handleChallenge(request: Request, response: Response): void {
const {
'hub.mode': mode,
'hub.verify_token': verifyToken,
'hub.challenge': challenge,
} = request.query as FacebookWebhookChallengeQuery
if (
mode === 'subscribe'
&& verifyToken === this.config.webhookVerifyToken
&& challenge
) {
response.status(200).send(challenge)
return
}
response.status(403).send(getCodeMessage(ResponseCode.ChannelWebhookInvalidVerifyToken, undefined, getLocale()))
}
private parseMetaBody(request: Request): FacebookWebhookBody {
const parsed = FacebookWebhookBodySchema.safeParse(request.body)
if (!parsed.success) {
this.logger.warn({ platform: AccountType.Facebook }, 'Facebook webhook body invalid')
return {}
}
return parsed.data
}
private async applyFacebookChange(change: FacebookWebhookChange): Promise<void> {
if (change.field !== FacebookWebhookField.Feed || change.value.comment_id) {
this.logger.log({ platform: AccountType.Facebook }, 'Facebook webhook event ignored')
return
}
if (!this.publishRecordRepo || !this.stateService) {
returnView on GitHub (pinned to d3aa8bea5b)
Solutions
- Copy the exact webhookVerifyToken from server config into the Meta App dashboard webhook verification field (or vice versa)
- Redeploy/restart the server so the current env value is loaded, confirming the right environment is running
- Re-attempt subscription in the Meta dashboard after aligning the token
- Ensure hub.challenge is passed through; do not manually test without all three hub params
Example fix
// before
// token hardcoded/drifted between dashboard and env
const WEBHOOK_VERIFY_TOKEN = 'old-token'
// after
const WEBHOOK_VERIFY_TOKEN = process.env.FACEBOOK_WEBHOOK_VERIFY_TOKEN
if (!WEBHOOK_VERIFY_TOKEN)
throw new Error('FACEBOOK_WEBHOOK_VERIFY_TOKEN is required') Defensive patterns
Strategy: validation
Validate before calling
if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] !== WEBHOOK_VERIFY_TOKEN)
return res.status(403).send('ChannelWebhookInvalidVerifyToken') Type guard
function isChallengeValid(req: Request, token: string): boolean {
return req.query['hub.mode'] === 'subscribe'
&& req.query['hub.verify_token'] === token
&& typeof req.query['hub.challenge'] === 'string'
&& req.query['hub.challenge'].length > 0
} Try / catch
app.get('/webhooks/facebook', (req, res) => {
if (isChallengeValid(req, process.env.FACEBOOK_WEBHOOK_VERIFY_TOKEN!)) {
return res.status(200).send(req.query['hub.challenge'])
}
res.status(403).send('ChannelWebhookInvalidVerifyToken')
}) Prevention
- Use the identical verify token string in the Meta dashboard and server env; rotate together
- Confirm the deployed environment's token before subscribing the webhook in Meta
- Return hub.challenge verbatim on success so Meta completes subscription
- Test subscription immediately after any token or deployment change
When it happens
Trigger: Meta calls GET /webhooks/facebook?hub.mode=subscribe&hub.verify_token=...&hub.challenge=... while the verify_token differs from the server's configured webhookVerifyToken, or hub.challenge is absent.
Common situations: Verify token entered in the Meta App dashboard differs from the server env value; token rotated on one side only; deploying the wrong environment (cn vs intl config) that holds a different token; URL queried manually for testing with a wrong token.
Related errors
- ChannelWebhookInvalidSignature
- ChannelWebhookInvalidVerifyToken
- InvalidModel
- VideoUploadVidNotFound
- InvalidAiTaskId
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/b47183fc5b11ff8f.
Report an issue: GitHub.