Facebook Messenger webhook verification failing although n8n webhook returns 200 (Cloud)

Hi,
I am using n8n Cloud and trying to verify a Facebook Messenger webhook.

  • Webhook URL: https://goglik.app.n8n.cloud/webhook/messenger-verify
  • Workflow is active, Webhook node returns HTTP 200 (Succeeded) on every request.
  • Each time I click Verify and save in the Meta Developer portal, I get:
    “The callback URL or verify token couldn’t be validated. Please verify the provided information or try again later.”
    So Facebook clearly reaches the webhook and n8n responds with 200, but Meta still fails verification.
    What could cause this, and is there anything I should change on the n8n side?
    Thanks!

Describe the problem/error/question

What is the error message (if any)?

Please share your workflow

Meta (Facebook) Developer portal:  "The callback URL or verify token couldn't be validated. Please verify the provided information or try again later."

Share the output returned by the last node

Webhook node returns HTTP 200 (Succeeded) on every verification request from Facebook.
No error in n8n, executions look normal.

Information on your n8n setup

  • n8n Cloud - Plan: (free trial / basic – whichever I am on) - Region: Europe - n8n version: latest available on Cloud (shows “Update (2 versions behind)” in UI) - Access: via browser (Chrome) on Windows

Welcome to the community @goga_nozadze

So basically, when Facebook’s server sends a GET request to https://goglik.app.n8n.cloud/webhook/messenger-verify, it receives the message {“message”:“Workflow was started”}. This is not the correct response format for Facebook’s verification process.

two steps to configure your Webhook node correctly:

  1. Set HTTP Method to GET: In your Webhook node’s settings, select HTTP Method as GET. This is because Facebook uses a GET request for the initial verification, not a POST.

  2. Respond with the Verification Token: Your workflow must read a query parameter from Facebook’s request and echo it back. In practice, this is easiest with a simple Function node or Code node placed right after the Webhook node. This node should:

Extract the hub.challenge parameter from the webhook request (e.g., {{ $node[“Webhook”].json[“query”][“hub.challenge”] }}).

Return the challenge value as a plain text response.

If you already have a POST webhook set up to process incoming messages, a good practice is to set up a second, separate workflow that is triggered only by a GET request, dedicated to this verification step.

Hope this answers your questions!