Skip to content
Templates

n8n error workflow: a daily Telegram digest of failed runs

A tested n8n error workflow that logs every failed execution to a data table and sends one Telegram digest each morning, grouped by workflow, or an all-clear.

By then8nblog Editors6 min read
Tested on n8n 2.39.8beginner~10 min setup
Illustration of the n8n failed runs digest template, one Telegram message each morning: the Error Trigger logs every failed production run, failures are saved in a data table, one digest at 8:00 grouped by workflow, and a daily all-clear

Workflow: n8n error workflow: a daily Telegram digest of failed runs

Download .json
When a workflow fails (Error Trigger)ErWhen a workflowfailsLog failure (Data Table)DTLog failureEvery morning at 8 (Schedule Trigger)ScEvery morning at 8Report settings (Edit Fields)EFReport settingsLoad failures (Data Table)DTLoad failuresBuild digest (Code)CoBuild digestSend digest (Telegram)TeSend digestClear reported rows (Data Table)DTClear reportedrows

Nodes (8)

  • Data Table ×3
  • Code
  • Edit Fields
  • Error Trigger
  • Schedule Trigger
  • Telegram

Credentials you'll need

  • Telegram API

To import: copy the JSON, open a workflow in n8n and paste onto the canvas (Ctrl+V or ⌘V). Credentials are never included; connect your own after importing.

This n8n error workflow catches every failed run of the workflows you link to it, stores each failure in a data table, and sends you one Telegram message each morning: how many runs failed, in which workflows, the last error of each, and a link to the failed execution. On a day with no failures you get a short all-clear instead, so a missing message tells you something is wrong too. It needs a Telegram bot and one n8n data table, and no n8n API key.

The short version

  • What it catches: any production run that fails in a workflow whose Error workflow setting points at this one. Manual test runs don't count; n8n's docs say the Error Trigger only runs when an automatic execution fails.
  • What you get: one Telegram message at 8:00, failures grouped by workflow with a count, the node that failed, the error message and a link to the last failed execution.
  • Why a digest: a flaky workflow that fails 30 times a night sends one line, not 30 alerts.
  • What you need: n8n with data tables, a Telegram bot and your chat ID. Tested on n8n 2.39.8.
  • Setup time: about 10 minutes, plus one setting change in each workflow you want to watch.

Daily digest of failed n8n executions

Download .json
When a workflow fails (Error Trigger)ErWhen a workflowfailsLog failure (Data Table)DTLog failureEvery morning at 8 (Schedule Trigger)ScEvery morning at 8Report settings (Edit Fields)EFReport settingsLoad failures (Data Table)DTLoad failuresBuild digest (Code)CoBuild digestSend digest (Telegram)TeSend digestClear reported rows (Data Table)DTClear reportedrows

Nodes (8)

  • Data Table ×3
  • Code
  • Edit Fields
  • Error Trigger
  • Schedule Trigger
  • Telegram

Credentials you'll need

  • Telegram API

To import: copy the JSON, open a workflow in n8n and paste onto the canvas (Ctrl+V or ⌘V). Credentials are never included; connect your own after importing.

How the workflow works

The workflow has two triggers and 8 nodes. The top branch runs every time a linked workflow fails; the bottom branch runs once a day.

When something fails:

  1. When a workflow fails (Error Trigger) receives the failure: the workflow's ID and name, and the execution's ID, URL, error message and the last node that ran.
  2. Log failure (Data table, Insert) writes one row to the failed_executions table, with the time it failed.

Every morning:

  1. Every morning at 8 (Schedule Trigger) starts the report.
  2. Report settings (Edit Fields (Set), JSON mode) holds your Telegram chat ID and how many workflows to list (maxWorkflows, 8 by default).
  3. Load failures (Data table, Get with Return All) reads every row logged since the last report. Always Output Data is on, so a day without rows still reaches the next node and produces the all-clear.
  4. Build digest (Code) groups the rows by workflow, sorts them by number of failures and writes the message. It also remembers the highest row ID it reported.
  5. Send digest (Telegram, Send Message) sends it with HTML formatting, so workflow names are bold and the execution link is clickable.
  6. Clear reported rows (Data table, Delete) removes the rows with an ID up to the one the digest reported, using the Less Than or Equal condition. A failure logged while the report runs has a higher ID, so it stays for tomorrow.

The delete runs after the Telegram node on purpose. If Telegram rejects the message, the run stops there and the rows stay in the table, so the next morning's digest still includes them.

What the digest looks like

This is the message from our test run, with two test workflows that failed on purpose (one with a Stop And Error node, one calling a domain that doesn't exist):

n8n daily report
3 failed executions in 2 workflows since the last report.

then8nblog test: invoice sync (fails on purpose): 2 failures
Last error in Push invoice to accounting: Accounting API returned 503 Service Unavailable
Open the last failed execution

then8nblog test: CRM import (fails on purpose): 1 failure
Last error in Fetch CRM contacts: The connection cannot be established, this usually occurs due to an incorrect host (domain) value
Open the last failed execution

"Open the last failed execution" is a link to that execution in your n8n editor, taken from the execution.url field the Error Trigger receives. With no failures, the message is:

n8n daily report
No failed executions since the last report.

What the Error Trigger receives

n8n's error handling docs list the data an error workflow gets. The Log failure node maps these fields:

ColumnExpressionNotes
workflowName{{ $json.workflow.name }}Always present
executionUrl{{ $json.execution?.url ?? '' }}Only when the execution was saved to the database
lastNode{{ $json.execution?.lastNodeExecuted ?? $json.trigger?.error?.node?.name ?? '' }}The node that failed
errorMessage{{ String($json.execution?.error?.message ?? $json.trigger?.error?.message ?? 'Unknown error').slice(0, 500) }}Capped at 500 characters

The ?. and ?? fallbacks are there because a failure in the trigger of a workflow arrives in a different shape. According to the docs, the workflow never ran in that case, so there's no execution ID or URL, and the error is under trigger.error instead of execution.error. The row is still logged, just without a link. If the expression syntax is new to you, see the n8n expressions cheat sheet.

Credentials you need

  • Telegram API: a bot token from Telegram's BotFather, saved as a Telegram credential in n8n. The workflow references it as Telegram account; pick yours in the Send digest node after import.

The data table nodes need no credentials.

Set it up

  1. Create the data table. In your project, open the Data tables tab and create a table named failed_executions with these columns: workflowId, workflowName, executionId, executionUrl, lastNode, errorMessage (all string) and failedAt (date). The three Data table nodes find the table by that name.
  2. Import the workflow. Copy the JSON above (or download it) and paste it onto an empty canvas, then save it.
  3. Add your Telegram credential to the Send digest node.
  4. Set your chat ID in the Report settings node, replacing <your-chat-id>. The website uptime monitor template explains how to find it.
  5. Publish the workflow. The morning schedule only runs once the workflow is published. We also published it before linking other workflows to it.
  6. Link the workflows you want to watch. In each one, open Options > Settings, choose this workflow under Error workflow, and save. n8n's docs say one error workflow can serve many workflows.
  7. Test it. You can't test the error branch by clicking Execute workflow in the failing workflow, because manual runs don't start error workflows. Make a small workflow with a Webhook trigger and a Stop And Error node, link it, publish it and call its production URL. A row should appear in failed_executions. Then open this workflow and run the Every morning at 8 trigger by hand to get the digest right away.

Customize it

  • Change the time. Edit Every morning at 8. It runs in the workflow's time zone, which comes from the instance setting (GENERIC_TIMEZONE when self-hosted) unless you change Timezone in the workflow's settings, as described in the Schedule Trigger docs.
  • Send it twice a day. Add a second rule to the Schedule Trigger. Each report covers everything logged since the previous one, so nothing is counted twice.
  • Skip the all-clear. Add a Filter node after Build digest that only passes items where {{ $json.failures }} is greater than 0. You lose the "n8n is alive" signal, though.
  • Send it somewhere else. Swap the Telegram node for Slack, email or Discord and use {{ $json.message }}. The text uses Telegram's HTML tags (<b>, <a href>), so adjust them for the new channel.
  • Keep a history. Remove Clear reported rows and add a filter on failedAt in Load failures instead. Watch the storage limit below.

Known limits and failure modes

  • Only linked workflows are covered. A workflow without this one set as its Error workflow fails silently as far as the digest is concerned. Link new workflows when you create them.
  • It can't report its own instance being down. If n8n is down at 8:00, no message arrives. That's why the all-clear exists: no message at all is the signal. For outages of the sites and APIs your workflows depend on, see the website uptime monitor.
  • A failed digest. n8n's docs say a workflow that contains an Error Trigger uses itself as its error workflow by default, and n8n 2.46.0 fixed a bug so a workflow's own Error Trigger runs when no error workflow is selected. On 2.46 or later, a failed digest run should therefore be logged and show up in the next digest. We tested on 2.39.8 and didn't test this path.
  • Long messages are shortened. Telegram allows 4096 characters per message. The Code node stops adding workflows at about 3500 characters or after maxWorkflows workflows and ends with "And N more workflows", and it shortens error messages to 200 characters.
  • Storage. All data tables in an instance share a default limit of 200 MiB, which self-hosted users can raise with N8N_DATA_TABLES_MAX_SIZE_BYTES. A row here is well under 1 KB, and the table is emptied every morning.
  • Execution counts. n8n's changelog for 2.28.0 says error workflow executions are excluded from the billable execution count, so logging a failure doesn't use up executions on plans that count them. The morning report is a normal scheduled run, one a day.

Sources

  1. Error handling (n8n docs)
  2. Error Trigger node (n8n docs)
  3. Stop And Error node (n8n docs)
  4. Data tables (n8n docs)
  5. Data table node row operations (n8n docs)
  6. Telegram node message operations (n8n docs)
  7. Schedule Trigger common issues, time zones (n8n docs)
  8. n8n changelog, 2.28.0 and 2.46.0 (GitHub)

then8nblog Editors

Editorial team

The then8nblog editorial team researches every article from n8n's release notes, documentation and source code, states the n8n version each guide was tested on, and has every post reviewed by a human editor before it goes live.