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

  1. Open the 'Webhook to call for Slack command' node and enable Raw Body (set rawBody: true); retest with a real Slack request.
  2. Confirm the binary property name is 'data' (default) or adjust the destructuring to the configured property name.
  3. 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.');
  4. 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

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


AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15). Data as JSON: /api/errors/b6c1929ffa33ed41. Report an issue: GitHub.