New to Kestra?
Use blueprints to kickstart your first workflows.
Audit Snowflake tasks and streams with Kestra. Detect failed task runs and stale CDC streams before downstream analytics pipelines break.
In Snowflake architectures, Tasks and Streams form the backbone of native Change Data Capture (CDC) and continuous ELT pipelines. Streams track row-level delta mutations (inserts, updates, deletes) on source tables using Snowflake Time Travel, while Tasks schedule SQL statements or stored procedures to consume those deltas downstream.
However, two failure modes silently plague production pipelines:
FAILED in SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY. After multiple consecutive failures, Snowflake automatically suspends dependent tasks in a task graph, stalling the pipeline.DATA_RETENTION_TIME_IN_DAYS, typically 1 to 90 days), the stream becomes stale (stale = true). Once a stream becomes stale, Snowflake permanently locks it from being read or advancing offsets, requiring manual intervention to drop and recreate the stream and potentially triggering costly full-table reconciliations.This blueprint establishes an automated operational health gate for Snowflake Tasks and Streams. Executing on an hourly schedule or on-demand, it queries SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY and SNOWFLAKE.ACCOUNT_USAGE.STREAMS to identify failed task executions and stale CDC streams. When an anomaly is detected, it dispatches an actionable incident triage card to Slack with root-cause error messages and remediation commands.
hourly_snowflake_health_audit trigger (io.kestra.plugin.core.trigger.Schedule) executes hourly. Shipped disabled: true by default so manual verification can occur first.audit_failed_tasks (io.kestra.plugin.jdbc.snowflake.Query) queries SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY over the configured lookback window (default 24 hours) for tasks with state = 'FAILED'. It uses COUNT(*) OVER() to preserve the true account-wide incident count while limiting detail rows to 50. Aliases are double-quoted to guarantee exact row-key casing.audit_stale_streams (io.kestra.plugin.jdbc.snowflake.Query) queries SNOWFLAKE.ACCOUNT_USAGE.STREAMS for active streams where stale = 'true' or stale_after < CURRENT_TIMESTAMP(). It similarly preserves the total count while retrieving detail records.evaluate_pipeline_health (io.kestra.plugin.core.flow.If) evaluates whether any failed tasks or stale CDC streams were returned.notify_dataops_incident (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers an operational card to Slack detailing affected task names, SQL error messages, and stale stream targets.log_healthy_state records confirmed health in execution logs.export_audit_manifest outputs a structured JSON telemetry summary for DataOps monitoring dashboards.errors block alerts Slack if the sentinel flow itself cannot connect to Snowflake.flowchart TD
A[Schedule: Hourly or On-Demand] --> B[audit_failed_tasks: Query TASK_HISTORY]
B --> C[audit_stale_streams: Query STREAMS]
C --> D{Failed Tasks or Stale Streams Detected?}
D -- Yes --> E[notify_dataops_incident: Slack Webhook]
D -- No --> F[log_healthy_state: Log Health Status]
E --> G[export_audit_manifest: JSON Telemetry]
F --> G
stale_after) preventing catastrophic stream staleness and data loss.Snowflake provides no out-of-the-box email or webhook alerting for task failures or stream staleness without writing complex custom stored procedures and external network access rules. Kestra delivers a declarative, serverless alternative: it connects over standard Snowflake JDBC, evaluates task history and stream metadata in a single pipeline, and coordinates alerts with your incident management channels.
| Name | Type | Default | Description |
|---|---|---|---|
lookback_hours |
INT | 24 |
Number of hours of historical Snowflake task execution history to inspect. |
{{ outputs.audit_failed_tasks.rows }}: Array of failed task records containing database_name, schema_name, task_name, state, error_code, error_message, scheduled_time, and total_failed_tasks.{{ outputs.audit_stale_streams.rows }}: Array of stale stream records containing database_name, schema_name, stream_name, table_name, stream_mode, stale_after, and total_stale_streams.{{ outputs.export_audit_manifest.value }}: Structured JSON telemetry manifest recording execution timestamp and incident status.SNOWFLAKE.ACCOUNT_USAGE shared schema.IMPORTED PRIVILEGES on the SNOWFLAKE database.SNOWFLAKE_JDBC_URL: Snowflake JDBC connection string (e.g. jdbc:snowflake://<account_locator>.snowflakecomputing.com?warehouse=COMPUTE_WH&db=SNOWFLAKE&schema=ACCOUNT_USAGE).SNOWFLAKE_USER: Service account username.SNOWFLAKE_PASSWORD: Service account password.SLACK_WEBHOOK_URL: Slack Incoming Webhook URL pointing to your designated DataOps channel.SNOWFLAKE_JDBC_URL, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD, and SLACK_WEBHOOK_URL in your Kestra namespace secrets.hourly_snowflake_health_audit for continuous monitoring.SNOWFLAKE.ACCOUNT_USAGE (such as TASK_HISTORY and STREAMS) can have up to 45 to 120 minutes of latency. For real-time sub-minute task status within a single database, you can point queries at TABLE(INFORMATION_SCHEMA.TASK_HISTORY(...)) instead.Stream has become stale. To recover, execute CREATE OR REPLACE STREAM <stream_name> ON TABLE <table_name>; and execute an initial reconciliation query against the source table.ALTER TASK <name> RESUME;.ALTER TASK <task_name> RESUME; for tasks suspended by transient warehouse pauses.