How to Automate Workflow Error Alerts with n8n

By The LightCube Labs team

The Problem

Automations fail quietly. A token expires on Friday, an API starts rate limiting, a webhook payload changes shape, and nobody notices until a customer asks why nothing happened. The opposite failure is just as bad: a flapping workflow that errors every minute floods the channel until everyone mutes it. Good alerting needs three things, a single place that catches every failure, a way to tell serious problems from noise, and a rule that stops the same error from alerting twice. This n8n workflow does all three, then adds a daily digest so recurring problems stay visible.

What You Will Need

Step-by-Step Workflow Setup

1 Catch failures with the Error Trigger

The n8n Error Trigger is special: n8n starts it for you, so you never expose a URL or schedule for the n8n error workflow.

The Error Trigger node starts a workflow whenever another workflow fails. It has no parameters. Instead, you open each workflow you want to monitor, go to Settings, and choose this workflow under Error Workflow. One alerting workflow can serve the whole instance.

Add an Error Trigger node and configure:

Node: Error Trigger
Parameters: none
Activation: not required for the trigger, but save the workflow
Monitored workflows: Settings > Error Workflow = "Error Alerts"

The node outputs the failed execution and workflow details. You read them with expressions such as:

Expression: {{ $json.workflow.name }}
Expression: {{ $json.execution.lastNodeExecuted }}
Expression: {{ $json.execution.error.message }}
Sample output:
{
  "execution": {
    "id": "231",
    "url": "https://n8n.yourcompany.example/execution/231",
    "retryOf": null,
    "error": { "message": "Request failed with status code 401", "stack": "NodeApiError: ..." },
    "lastNodeExecuted": "Create Invoice",
    "mode": "trigger"
  },
  "workflow": { "id": "14", "name": "Invoice sync" }
}

Use the manual Test workflow button to run the trigger with sample data while you build. Real errors only arrive after you link a monitored workflow.

2 Extract details and classify severity

Because n8n gives the same payload shape for every workflow, one n8n Code node can classify failures from the whole instance.

A Code node flattens the payload and assigns a type from a small taxonomy: timeout, auth, rate-limit, data, or unknown. Order matters. Check the most specific patterns first.

Node: Code
Mode: Run Once for Each Item
Language: JavaScript

const e = $json.execution;
const msg = (e.error && e.error.message) || 'Unknown error';
const m = msg.toLowerCase();
let type = 'unknown';
if (/timeout|timed out|etimedout|econnreset/.test(m)) type = 'timeout';
else if (/401|403|unauthorized|forbidden|invalid token|credential/.test(m)) type = 'auth';
else if (/429|rate limit|too many requests/.test(m)) type = 'rate-limit';
else if (/undefined|cannot read|invalid json|missing field|400/.test(m)) type = 'data';
const workflow = $json.workflow.name;
const node = e.lastNodeExecuted || 'unknown';
return { json: { timestamp: new Date().toISOString(), workflow, node,
  message: msg, type, executionId: e.id, url: e.url,
  key: workflow + '|' + node + '|' + msg.slice(0, 80) } };
Sample output:
{
  "timestamp": "2026-11-04T14:22:09.000Z",
  "workflow": "Invoice sync",
  "node": "Create Invoice",
  "type": "auth",
  "executionId": "231",
  "key": "Invoice sync|Create Invoice|Request failed with status code 401"
}

The key field combines workflow, node, and the first 80 characters of the message. It is the identity used for duplicate checks, and truncating it avoids treating messages that contain changing ids as different errors.

3 Deduplicate against the error log

The sheet acts as the memory that n8n executions lack, and the n8n Google Sheets node makes it easy to read and write.

Read recent rows with a Google Sheets node, then let a Code node decide whether this error has already been logged within the last hour.

Node: Google Sheets
Operation: Get Row(s)
Document: Ops Error Log
Sheet: Error Log
Return All: on
Settings: Always Output Data: on

Node: Code
Mode: Run Once for All Items

const cur = $('Code').first().json;
const rows = $input.all().map(i => i.json);
const cutoff = Date.now() - 60 * 60 * 1000;
const dup = rows.some(r => r.key === cur.key && new Date(r.timestamp).getTime() > cutoff);
const repeats = rows.filter(r => r.key === cur.key).length;
return [{ json: { ...cur, isNew: dup === false, repeats } }];

Enable Always Output Data on the Sheets node. On an empty sheet it would otherwise return no items, and the Code node would never run.

Sample output:
{
  "key": "Invoice sync|Create Invoice|Request failed with status code 401",
  "isNew": true,
  "repeats": 0
}

4 Decide what is critical

The n8n IF node keeps the alert rule readable, and you can add more conditions later without changing the surrounding n8n nodes.

The IF node gates the alert. Only new errors that are critical reach Slack: any auth failure, or a timeout that has repeated.

Node: IF
Combinator: AND
Condition 1: {{ $json.isNew }} is true
Condition 2 (OR group):
  {{ $json.type }} equals auth
  {{ $json.type }} equals timeout AND {{ $json.repeats }} is greater than or equal to 2

The true branch alerts and logs. Connect the false branch to the logging node as well, so suppressed errors still appear in the sheet and the daily digest.

5 Alert Slack with a suggested fix

The n8n Slack node supports plain text with simple formatting, which is enough for an ops channel fed by n8n.

The Slack node posts the details, a link to the execution, and a next action chosen from the error type. A lookup object inside the expression keeps the node simple.

Node: Slack
Resource: Message
Operation: Send
Channel: #ops-alerts
Text: *{{ $json.type.toUpperCase() }}* in {{ $json.workflow }} at node {{ $json.node }}
Message: {{ $json.message }}
Execution: {{ $json.url }}
Suggested fix: {{ { auth: 'Reconnect the credential and check token expiry.',
  timeout: 'Raise the node timeout or check the remote service status.',
  'rate-limit': 'Add a Wait node or enable batching.',
  data: 'Inspect the input item for missing fields.',
  unknown: 'Open the execution and read the full stack.' }[$json.type] }}
Sample Slack message:
AUTH in Invoice sync at node Create Invoice
Request failed with status code 401
Execution: https://n8n.yourcompany.example/execution/231
Suggested fix: Reconnect the credential and check token expiry.

6 Append to the error log

Writing every error to the log from n8n gives you free history for analysis later.

Every error, alerted or suppressed, goes into the sheet. That sheet is both the memory for deduplication and the data source for the digest.

Node: Google Sheets
Operation: Append Row
Sheet: Error Log
Mapping Column Mode: Map Each Column Manually
timestamp: {{ $json.timestamp }}
workflow: {{ $json.workflow }}
node: {{ $json.node }}
message: {{ $json.message }}
type: {{ $json.type }}
execution_id: {{ $json.executionId }}
key: {{ $json.key }}

Use a Merge node set to Append before this step so both IF branches reach the same logging node.

7 Build the daily digest

The scheduled line and the error line share one n8n workflow, so a single n8n export contains the entire monitoring setup.

The second flow lives in the same workflow on its own line. Start with a Schedule Trigger at 18:00, read today's rows with a Google Sheets node, summarize in a Code node, and mail the result with a Send Email node.

Node: Schedule Trigger
Trigger Interval: Days, Trigger at Hour: 6pm

Node: Code
Mode: Run Once for All Items

const rows = $input.all().map(i => i.json);
const today = new Date().toISOString().slice(0, 10);
const t = rows.filter(r => String(r.timestamp).startsWith(today));
const count = (f) => t.reduce((a, r) => (a[r[f]] = (a[r[f]] || 0) + 1, a), {});
const top = Object.entries(count('key')).sort((a, b) => b[1] - a[1]).slice(0, 3);
return [{ json: { total: t.length, byWorkflow: count('workflow'), byType: count('type'), top } }];

Node: Send Email
To Email: ops@yourcompany.example
Subject: Daily error digest: {{ $json.total }} errors
Text: By type: {{ JSON.stringify($json.byType) }}
Sample digest data:
{
  "total": 14,
  "byWorkflow": { "Invoice sync": 9, "Lead intake": 5 },
  "byType": { "auth": 9, "timeout": 3, "data": 2 },
  "top": [["Invoice sync|Create Invoice|Request failed with status code 401", 9]]
}

Sort by count to expose the top recurring errors. Those are the fixes that remove the most noise.

Before you rely on this n8n workflow, build a throwaway workflow that always fails, set its Error Workflow to this one, and run it twice. The first run should alert Slack and the second should be suppressed by the n8n deduplication step. That single test proves the n8n trigger, the n8n classification, and the log all work together.

Troubleshooting

The Error Trigger never runs

The monitored workflow has no Error Workflow selected in its settings, or the failure happened during a manual test run. Error workflows fire for production executions only, so activate the monitored workflow and let it run on its trigger. In n8n, open Settings on the monitored workflow and look at the Error Workflow field.

The error message field is empty or lastNodeExecuted is missing

Trigger-level failures, such as a webhook that cannot start, have no last node. The Code step above falls back to unknown. Check the execution link for the stack trace in those cases. The n8n execution page shows the stack trace for these cases.

Duplicates still get through

Messages that embed timestamps or record ids create a new key each time. Strip digits with msg.replace(/[0-9]+/g, 'N') before building the key, and keep the sheet short by archiving rows older than 7 days. Review the n8n sheet rows to see which keys repeat.

Free n8n Workflow Resources

Get started with the free workflow pack on the LightCube Labs templates page.

Production-Ready Workflow Packs

Get this workflow and more, with setup guides, editable configurations, and a shared failure-alert system.

View the Starter ($29) and Pro ($99) Packs

Frequently Asked Questions

Does the Error Trigger catch errors in the error workflow itself?

No. If the alerting workflow fails, nothing catches it. Keep it simple, test it with a deliberate failure, and consider a separate uptime check that pings the instance from outside. A simple external ping can watch your n8n instance itself.

Why classify errors instead of alerting on everything?

Classification lets severity drive behavior. Auth failures usually block all runs and need immediate action, while a single data error in one item rarely does. The type also selects the suggested fix text shown in Slack. n8n lets you change the pattern list in one Code node.

Can one error workflow monitor many n8n workflows?

Yes. Point each workflow's Error Workflow setting at it. The workflow name in the payload tells you the source, and the digest groups counts by workflow. The n8n Error Trigger passes the workflow name every time.

Why log suppressed duplicates at all?

The counts matter. A single hourly error that repeats 40 times in a day is a different problem from one that happened once, and only the log can show that in the digest. You can open the n8n log sheet and filter on the key column.