How to Set Up Alerts and Monitoring for Data Pipeline Failures in Kestra: A Complete Guide
Kestra provides built-in event-driven hooks and Prometheus metrics that let you detect pipeline failures instantly and send alerts to Slack, email, or webhooks without external monitoring tools.
The DataTalksClub/data-engineering-zoomcamp repository demonstrates production-grade observability patterns using Kestra's native notification plugins and metrics endpoints. To set up alerts and monitoring for data pipeline failures in Kestra, you configure onFailure hooks in your flow definitions, enable Prometheus scraping on the server, and route notifications through built-in plugins that execute automatically when tasks fail.
Understanding Kestra's Three-Layer Monitoring Architecture
Kestra's monitoring stack operates through three distinct layers that work together to provide complete visibility into your data pipelines.
Health-Check and Metrics Layer
The Kestra server exposes Prometheus metrics at /actuator/prometheus and a health endpoint at /actuator/health. These endpoints allow continuous visibility into server status and performance. You can scrape these metrics using any Prometheus instance and visualize them in Grafana to track system-level health.
Failure Detection via Event Hooks
Every workflow run emits lifecycle events (RUNNING, SUCCESS, FAILED, KILLED). Kestra detects failures by hooking into these events using Triggers or Listeners defined directly in your flow YAML. This event-driven architecture ensures immediate detection when any task or workflow fails.
Alert Delivery with Notification Plugins
Kestra ships with dedicated notification plugins that push alerts to external systems. Available plugins include io.kestra.plugin.notifications.slack.SlackWebhook, io.kestra.plugin.notifications.email.Email, and io.kestra.plugin.notifications.webhook.Webhook. These execute from an onFailure section of a flow or from dedicated notification tasks that run only when parent tasks fail.
Configuring Failure Alerts with onFailure Hooks
The onFailure block in Kestra flows runs only when the parent task throws an exception. This pattern keeps alert logic version-controlled and testable alongside your pipeline code.
Slack Alert Configuration
The following example from 02-workflow-orchestration/flows/02_python.yaml demonstrates sending a Slack notification when a Python script fails:
id: python_example
namespace: data_zoomcamp
tasks:
- id: run_script
type: io.kestra.plugin.scripts.python.Script
script: |
import time, random
time.sleep(2)
if random.random() > 0.5:
raise Exception("Random failure")
onFailure:
- id: slack_alert
type: io.kestra.plugin.notifications.slack.SlackWebhook
webhookUrl: "{{ secret('SLACK_WEBHOOK_URL') }}"
message: |
:warning: *Kestra flow failed*
• Flow: `{{ flow.id }}`
• Task: `{{ task.id }}`
• Run ID: `{{ run.id }}`
• Error: `{{ task.errors }}`
The {{ secret('SLACK_WEBHOOK_URL') }} expression pulls the webhook URL from Kestra's secret store, keeping credentials out of version control.
Email Alert Configuration
For teams preferring email notifications, use the built-in SMTP plugin:
tasks:
- id: extract_data
type: io.kestra.plugin.jdbc.postgresql.Query
sql: SELECT * FROM raw.taxi
onFailure:
- id: email_alert
type: io.kestra.plugin.notifications.email.Email
host: smtp.gmail.com
port: 587
username: "{{ secret('SMTP_USER') }}"
password: "{{ secret('SMTP_PASS') }}"
from: "kestra@yourdomain.com"
to:
- "data-eng@example.com"
subject: "[Kestra] {{ flow.id }} failed"
body: |
The task `{{ task.id }}` in flow `{{ flow.id }}` failed.
Run ID: {{ run.id }}
Error details:
{{ task.errors }}
Enabling Prometheus Metrics and Grafana Dashboards
After starting Kestra with Docker Compose using the repository's docker-compose.yml, enable the Prometheus exporter by setting the environment variable:
# 02-workflow-orchestration/docker-compose.yml
services:
kestra:
image: kestra/kestra:latest
ports:
- "8080:8080"
environment:
- KESTRA_SERVER_METRICS_ENABLED=true
Scrape http://localhost:8080/actuator/prometheus from your Prometheus server. Import the official Kestra Grafana dashboard to visualize run counts, failure rates, and task-level latency metrics.
Building Reusable Alert Flows for Centralized Management
For larger deployments, route all failure events to a single webhook that forwards to PagerDuty, Opsgenie, or custom incident-response services. Define a reusable notification flow and call it from any other flow's onFailure using the io.kestra.plugin.core.flow.Trigger task.
Create a centralized alert forwarder:
# flows/alert_forwarder.yaml
id: alert_forwarder
namespace: shared
tasks:
- id: forward
type: io.kestra.plugin.notifications.webhook.Webhook
url: "{{ secret('ALERT_WEBHOOK_URL') }}"
method: POST
headers:
Content-Type: application/json
body: |
{
"flow": "{{ flow.id }}",
"task": "{{ task.id }}",
"runId": "{{ run.id }}",
"status": "{{ task.state }}",
"error": "{{ task.errors }}"
}
Reference this from any other flow:
onFailure:
- id: forward_failure
type: io.kestra.plugin.core.flow.Trigger
flowId: alert_forwarder
Summary
- Kestra exposes Prometheus metrics at
/actuator/prometheusand health checks at/actuator/healthfor infrastructure monitoring. - The
onFailurehook executes notification tasks only when specific tasks fail, keeping alert logic co-located with pipeline definitions. - Built-in notification plugins like
io.kestra.plugin.notifications.slack.SlackWebhooksupport Slack, email, and generic webhooks. - Reusable alert flows using
io.kestra.plugin.core.flow.Triggerenable centralized incident management across multiple pipelines. - Secret management via
{{ secret('KEY') }}expressions keeps credentials secure while maintaining Infrastructure-as-Code principles.
Frequently Asked Questions
How do I access Kestra's Prometheus metrics?
Configure your Prometheus server to scrape http://<kestra-host>:8080/actuator/prometheus after setting KESTRA_SERVER_METRICS_ENABLED=true in your environment variables. The endpoint exposes counters for workflow executions, task durations, and failure rates that you can visualize in Grafana dashboards.
Can I send alerts to multiple channels simultaneously?
Yes. Define multiple tasks within a single onFailure block, or create a dedicated notification flow that triggers multiple notification tasks in parallel. Each task can target a different channel (Slack, email, webhook) using the respective plugin types.
How do I secure webhook URLs and credentials in alert configurations?
Use Kestra's secret store with the {{ secret('KEY_NAME') }} expression syntax. This keeps sensitive values out of your YAML files while allowing the flow to access them at runtime. Store the actual values in Kestra's secrets management UI or through environment variables depending on your deployment mode.
What's the difference between onFailure and triggers for monitoring?
The onFailure hook runs within the same flow context immediately when a specific task fails, giving you granular control per task. Triggers (using io.kestra.plugin.core.flow.Trigger) listen for state changes across flows and can centralize alerting logic, making them ideal for platform teams managing multiple pipelines from a single notification service.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →