Handle Workflow Errors with Global and Local Strategies

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Kestra provides multiple ways to handle errors, helping you both identify issues and decide whether your flows should stop or continue running after an error.

Error handling mechanisms

Three mechanisms control flow behavior when tasks fail: errors, allowFailure/allowWarning, and afterExecution.

MechanismBehavior
errorsTasks in this list run when a task or the flow fails; executes sequentially after the failure
allowFailureMarks a failed task’s outcome as a warning instead of propagating the failure; downstream tasks continue
allowWarningMarks a warned task’s outcome as success; downstream tasks continue
afterExecutionRuns after the execution reaches a terminal state; receives the final execution state via runIf

For post-run actions based on the final execution state, see afterExecution.

errors component

errors is a list of tasks executed at the flow level when an error occurs. Tasks run sequentially.

Flow-level error handler with Slack notification:

id: errors
namespace: company.team
description: This will always fail
tasks:
- id: failed_task
type: io.kestra.plugin.core.execution.Fail
errors:
- id: alert_on_failure
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
url: "{{ secret('SLACK_WEBHOOK') }}"
messageText: "Failure alert for flow {{ flow.namespace }}.{{ flow.id }} with ID {{ execution.id }}"

Global error handler

Global error handler using tasksWithState() to log the failed task ID:

id: errors
namespace: company.team
tasks:
- id: failed
type: io.kestra.plugin.core.execution.Fail
errors:
- id: error_handler
type: io.kestra.plugin.core.log.Log
message: I'm failing task '{{ tasksWithState('FAILED')[0]['taskId'] }}' # tasksWithState() returns an array; [0] gets the first failed task.
level: INFO

Local error handler

A local error handler applies only to the children of the flowable task it is defined on (t2 in this example). Errors from t1 are not caught here:

id: errors
namespace: company.team
tasks:
- id: parent-seq
type: io.kestra.plugin.core.flow.Sequential
tasks:
- id: t1
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }} > {{ taskrun.startDate }}"
- id: t2
type: io.kestra.plugin.core.flow.Sequential
tasks:
- id: t2-t1
type: io.kestra.plugin.core.execution.Fail
errors:
- id: error-t1
type: io.kestra.plugin.core.debug.Return
format: "Error in {{ task.id }}"

allowFailure and allowWarning properties

By default, a failed task stops all downstream tasks. Adding allowFailure: true lets downstream tasks continue despite the error; the execution finishes in a WARNING state.

id: allow_failure
namespace: company.team
description: Allows a task failure and continues downstream; execution finishes in WARNING state.
tasks:
- id: first
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }} > {{ taskrun.startDate }}"
- id: allow_failure
type: io.kestra.plugin.core.execution.Fail
allowFailure: true
- id: last
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }} > {{ taskrun.startDate }}"

allowWarning works the same way, but the execution finishes in a SUCCESS state even if warnings occur:

id: allow_warning
namespace: company.team
description: Allows a task warning and continues downstream; execution finishes in SUCCESS state.
tasks:
- id: first
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }} > {{ taskrun.startDate }}"
- id: allow_warning
type: io.kestra.plugin.scripts.python.Script
allowWarning: true
beforeCommands:
- pip install kestra
script: |
from kestra import Kestra
logger = Kestra.logger()
logger.warning("WARNING signals something unexpected.")

Was this page helpful?