For the broader set of patterns this fits into, see our guide to production-grade n8n error handling. This post is the concrete version: one workflow, ready to import.

If you’ve spent any time building with n8n, you’ve felt the frustration of a workflow that fails silently in the middle of the night. An API times out, incoming data is malformed, or a service is temporarily down, and your critical automation grinds to a halt without a whisper. For basic zaps, this is an annoyance. For production workflows, it’s a critical failure.

The default n8n behavior, stopping the workflow on any error, is safe, but it’s not robust. To build truly reliable, enterprise-grade automations, you need a centralized, intelligent error handling strategy.

This guide will show you exactly how to build one: a reusable global error-handling sub-workflow that you can set up once and connect to all your other workflows for consistent, informative, and actionable error monitoring.

The Problem: Unhandled Errors are Silent Killers

Most n8n users handle errors in one of three ways:

  1. Not at all: They rely on the default stop-on-failure behavior and manually check the Executions log. (Not scalable)
  2. Per-Node: They use the “Continue On Error” setting for individual nodes. (Can get messy and hide real problems)
  3. Ad-Hoc: They build custom error branches within each workflow. (Repetitive and inconsistent)

A production-grade system needs something better. It needs a “fire department” that gets automatically dispatched whenever there’s a problem, no matter where it occurs.

The Solution: A Reusable Global Error Handler

We will build a separate, dedicated workflow whose only job is to catch, process, and report on errors from any other workflow.

Here’s the logic:

  1. Catch the Error: Using the Error Trigger node, this workflow will activate automatically when another workflow fails.
  2. Format the Context: It will extract the most important information: what workflow failed, which node caused the error, the execution URL, and the specific error message.
  3. Log It: It will send this structured data to a permanent log, like a Supabase table, for historical analysis.
  4. Alert a Human: It will send a clean, nicely formatted, and immediate notification to a service like Telegram or Slack.

Building the Workflow

You can build this yourself in a few minutes. Here are the nodes you’ll need:

  1. Error Trigger: This is the entry point. It’s what allows this workflow to be designated as the default error handler for your entire n8n instance.
  2. Set Node: To organize the data. We’ll map the messy JSON from the error trigger into clean, easy-to-use variables.
  3. Code Node: To format the alert message using Javascript. This gives us full control over the output, allowing us to include markdown and make the alert highly readable.
  4. HTTP Request Node: To log the structured error data to our Supabase n8n_error_log table.
  5. Telegram Node: To send the immediate alert.

Ready-to-Use Workflow JSON

To save you time, here is the complete, importable JSON for this workflow. Save it as a .json file and import it directly into your n8n canvas.

{
  "name": "Global Error Handler",
  "nodes": [
    {
      "parameters": {},
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "workflowId",
              "value": "={{ $json.execution.workflowId }}"
            },
            {
              "name": "workflowName",
              "value": "={{ $json.workflow.name }}"
            },
            {
              "name": "executionId",
              "value": "={{ $json.execution.id }}"
            },
            {
              "name": "executionUrl",
              "value": "={{ $json.execution.url }}"
            },
            {
              "name": "errorNode",
              "value": "={{ $json.error.node.name }}"
            },
            {
              "name": "errorMessage",
              "value": "={{ $json.error.message }}"
            },
            {
              "name": "errorStack",
              "value": "={{ $json.error.stack }}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set Error Context",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        470,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const alertMessage = `🚨 *n8n Workflow Error*\\n\\n*Workflow:* [${$json.workflowName}](${$json.executionUrl})\\n*Failing Node:* ${$json.errorNode}\\n\\n*Error:*\\n` + '```\\n' + $json.errorMessage + '\\n```';\n\nreturn { alertMessage };"
      },
      "name": "Format Alert",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        690,
        300
      ]
    },
    {
      "parameters": {
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "text": "={{ $('Format Alert').item.json.alertMessage }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "name": "Notify Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1130,
        400
      ],
      "credentials": {
        "telegramApi": {
          "id": "YOUR_TELEGRAM_CREDENTIAL_ID",
          "name": "Your Telegram Credential"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/n8n_error_log",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SUPABASE_KEY }}"
            }
          ]
        },
        "sendBody": true,
        "jsonBody": "={\n  \"workflow_id\": \"{{ $json.workflowId }}\",\n  \"workflow_name\": \"{{ $json.workflowName }}\",\n  \"execution_id\": \"{{ $json.executionId }}\",\n  \"execution_url\": \"{{ $json.executionUrl }}\",\n  \"failing_node\": \"{{ $json.errorNode }}\",\n  \"error_message\": \"{{ $json.errorMessage }}\",\n  \"error_stack\": \"{{ $json.errorStack }}\"\n}",
        "options": {}
      },
      "name": "Log to Supabase",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1130,
        200
      ]
    }
  ],
  "connections": {
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Set Error Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Error Context": {
      "main": [
        [
          {
            "node": "Format Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Alert": {
      "main": [
        [
          {
            "node": "Log to Supabase",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {},
  "staticData": null
}

How to Configure It

  1. Import the Workflow: Save the JSON above and import it into n8n.
  2. Set as Default Error Workflow: In your n8n instance settings (or via environment variables), set this new workflow as the “Error Workflow”. This is the magic step that links it to all other workflow failures.
  3. Update Credentials:
    • In the Log to Supabase node, ensure your Supabase URL and Key are correctly referenced from your environment variables or credentials.
    • In the Notify Telegram node, select your Telegram credential and set the correct Chat ID to send the alert to.

Conclusion: Build for Reliability

By investing 15 minutes to set up a global error handler, you fundamentally increase the reliability of your entire automation suite. You move from a reactive state of manually checking logs to a proactive state where your system tells you exactly what’s wrong, the moment it happens.

This is a foundational pattern for anyone serious about building production-ready automations in n8n.

Frequently asked questions

How do I make this the default error handler for all my n8n workflows?

After importing the workflow, go to your n8n instance settings (or set it via environment variable) and choose it as the Error Workflow. That single setting links every other workflow's failures to this one automatically, you don't need to configure anything per workflow.

Why use an Error Trigger workflow instead of Continue On Error on each node?

Continue On Error hides failures at the node level and gets inconsistent fast across dozens of workflows. A centralized Error Trigger workflow catches every failure in one place with one consistent format, so you fix the alerting logic once instead of copy-pasting it everywhere.

Can I log errors somewhere other than Supabase?

Yes, the HTTP Request node in this workflow just needs a table or endpoint to POST to. Swap in any database with a REST API, or point it at a spreadsheet API, a webhook, or your own logging service.

Want this built for you?

We design and ship production n8n automation for agencies, and train your team to own it.

Book a build →