Zie619/n8n-workflows · critical · Error
Missing binary data
Error message
Missing binary data
What it means
Thrown by 'Validate webhook signature' when $('Webhook to call for Slack command').first() has no binary property. Slack signature verification needs the RAW request body: the n8n Webhook node only stores the raw body as binary (default property 'data') when its 'Raw Body' option (rawBody: true, or 'Include Raw Body' in the UI) is enabled. Without it, item.binary is undefined and this guard fires before any HMAC check runs.
Source
Thrown at workflows/Webhook/0453_Webhook_Code_Create_Webhook.json:861
560,
280
],
"parameters": {
"jsCode": "const text = $input.first().json.command_text;\nconst parts = text.split(' ');\n\n\n// GET COMMAND\n// for example /cloudbot info mutasem\n// should return \"info\"\nconst command = parts[0];\n\n\n// GET FLAGS \n// for example /cloudbot info mutasem --test --flag\n// should return ['--test', '--flag']\nconst flags = parts.filter((part) => part.startsWith('--'));\n\n\n// GET PARAMS\n// for example /cloudbot info mutasem test\n// should return [\"mutasem\", \"test\"]\nlet params = parts\n .filter((part, i) => i > 0 && !part.startsWith('--'));\nparams = params.filter((param, i) => {\n if (param === '-e') {\n return false;\n }\n if (params[i - 1] === '-e') {\n return false;\n }\n\n return true;\n});\n\n\n// GET ENV VARS\n// for example /cloudbot info mutasem -e env=prod\n// should return {env: \"prod\"}\nconst env = parts.filter((val, i) => {\n return i > 0 && parts[i - 1] === '-e';\n})\n .reduce((accu, opt) => {\n if (!opt.includes('=')) {\n return accu;\n }\n\n const key = opt.split('=')[0];\n const val = opt.split('=')[1];\n \n accu[key] = clean(val);\n return accu;\n}, {});\n\n// Add workflow to run\nconst commands = $input.first().json.commands;\nlet workflow;\nif (commands[command]) {\n workflow = commands[command];\n}\n\nreturn {\n ...$input.first().json,\n command,\n flags,\n env,\n params,\n workflow,\n}\n\nfunction clean(str) {\n return str.replaceAll(`‘`, '\\'').replaceAll('“', '\"').replaceAll('”', '\"').replaceAll('’', '\\'');\n}"
},
"typeVersion": 1,
"notes": "This code node performs automated tasks as part of the workflow."
},
{
"id": "22b8502c-dec3-4456-9947-639761517881",
"name": "Validate webhook signature",
"type": "n8n-nodes-base.code",
"position": [
100,
280
],
"parameters": {
"jsCode": "const SIGNING_SECRET = $input.first().json.slack_secret_signature;\nconst item = $('Webhook to call for Slack command').first();\n\nif (!item.binary) {\n throw new Error('Missing binary data');\n}\n\nconst crypto = require('crypto');\nconst { binary: { data } } = item;\n\nif (\n !item.json.headers['x-slack-request-timestamp'] ||\n Math.abs(\n Math.floor(new Date().getTime() / 1000) -\n +item.json.headers['x-slack-request-timestamp']\n ) > 300\n) {\n throw new Error('Unauthorized, request not fresh');\n}\n\nconst rawBody = Buffer.from(data.data, 'base64').toString()\n\n// compute the basestring\nconst baseStr = `v0:${item.json.headers['x-slack-request-timestamp']}:${rawBody}`;\n\n// extract the received signature from the request headers\nconst receivedSignature = item.json.headers['x-slack-signature'];\n\nconst expectedSignature = `v0=${crypto.createHmac('sha256', SIGNING_SECRET)\n.update(baseStr, 'utf8')\n.digest('hex')}`;\n\n// match the two signatures\nif (expectedSignature !== receivedSignature) {\nthrow new Error('Unauthorized, umatched signatures');\n}\n\nreturn $input.all();"
},
"typeVersion": 2,
"notes": "This code node performs automated tasks as part of the workflow."
}
],
"pinData": {},
"connections": {
"ee413d6c-dad3-4e57-b08d-ffd0f84c682e": {
"main": [
[
{
"node": "error-handler-ee413d6c-dad3-4e57-b08d-ffd0f84c682e",
"type": "main",
"index": 0
}
],
[
{View on GitHub (pinned to 94007c1445)
Solutions
- Open the 'Webhook to call for Slack command' node and enable Raw Body (set rawBody: true); retest with a real Slack request.
- Confirm the binary property name is 'data' (default) or adjust the destructuring to the configured property name.
- Guard with a clear message: if (!item.binary || !item.binary.data) throw new Error('Raw body missing: enable the Raw Body option on the webhook node.');
- Verify with console.log(Object.keys(item.binary || {})) once working, then remove.
Example fix
// before
const item = $('Webhook to call for Slack command').first();
if (!item.binary) {
throw new Error('Missing binary data');
}
const { binary: { data } } = item;
// after
const item = $('Webhook to call for Slack command').first();
if (!item.binary || !item.binary.data) {
throw new Error('Missing binary data: enable the "Raw Body" option on the webhook node so the raw Slack payload is stored as binary.');
}
const { binary: { data } } = item; Defensive patterns
Strategy: validation
Validate before calling
const item = $('Webhook to call for Slack command').first();
if (!item.binary || !item.binary.data) {
throw new Error('Missing binary data: enable the Raw Body option on the webhook node — Slack signature verification requires the exact raw payload.');
} Type guard
const hasRawBody = (item) => item?.binary?.data != null && typeof item.binary.data.data === 'string';
Try / catch
try {
verifySlackSignature(item, SIGNING_SECRET);
} catch (e) {
// signature failures should be surfaced, never swallowed — this is a security control
throw new Error(`Slack signature verification failed: ${e.message}`);
} Prevention
- Always enable Raw Body on webhook nodes whose payloads must be signature-verified (Slack, Stripe, GitHub).
- Treat this error as a config defect, not a runtime flake: it means the raw body was never captured, so every request would fail.
- Test the whole chain with a real Slack request after any webhook node recreation or n8n upgrade.
When it happens
Trigger: Webhook node created without the raw-body option so Slack POSTs arrive with only parsed json (no binary.data), the binary property renamed, or a test invocation (e.g., from the editor 'test' URL with a manually crafted item) that never had binary. Also fires if an intermediate node stripped binary data.
Common situations: Recreating the webhook node and forgetting to tick 'Raw Body' (the single most common cause), n8n version upgrades resetting node options, or copying this verification code into a workflow whose webhook lacks the option.
Related errors
- Invalid quantity: ${input["Quantity Received"]}
- Invalid price: ${input["Unit Price"]}
- Invalid quantity Requested: ${quantityRequested}. Must be gr
- Product ID is missing
- Invalid quantity requested: ${quantityRequested}
AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15).
Data as JSON: /api/errors/b6c1929ffa33ed41.
Report an issue: GitHub.