Skip to content

Lifecycle Handlers

Lifecycle handlers let you run extra steps after the main DAG completes. Use the handlerOn block to trigger notifications, clean up resources, or kick off follow-up jobs without duplicating logic inside individual steps.

Supported Triggers

HandlerTriggerTypical use cases
successAll steps completed successfully, or the DAG ended in partialSuccessDeliver success notifications, enqueue downstream jobs
failureThe DAG ended with an error statusPage on-call, collect diagnostics
cancelA stop request interrupted the run (manual stop, queue eviction, timeout cancellation)Roll back partial work, release locks
exitAlways runs after the status-specific handler finishes (including when it fails or is skipped)File system clean-up, archival tasks

Only the handlers you define are executed. The scheduler runs the status-specific handler first (if present) and the exit handler last.

Basic Definition

yaml
# dag.yaml
handlerOn:
  success:
    command: notify.sh "${DAG_NAME} (${DAG_RUN_ID}) finished" # runs after a clean finish
  failure:
    command: alert.sh "${DAG_NAME} failed" "logs=${DAG_RUN_LOG_FILE}"
  cancel:
    command: rollback.sh --lock ${LOCK_NAME}
  exit:
    command: rm -rf /tmp/${DAG_RUN_ID} # always runs

steps:
  - command: ./extract.sh
  - command: ./load.sh

Each handler is a normal step definition. You can use command, script, run, executor, containers, timeouts, or any other step field that makes sense for a single task.

Execution Model

  • The scheduler waits for all main steps to finish before evaluating handlers.
  • It chooses the status-specific handler based on the final DAG status (partialSuccess behaves like success).
  • After the status-specific handler finishes (or if none was defined), the exit handler runs last.
  • Handlers are executed sequentially and synchronously. The DAG is still considered running until they finish.
  • If a handler exits with a non-zero status, the overall DAG run ends in error, even if every main step succeeded.
  • Handler logs appear alongside other steps in the run history and respect the same log retention policy.

Patterns and Integrations

Send Email with the Mail Executor

yaml
handlerOn:
  failure:
    executor:
      type: mail
      config:
        to: oncall@company.com
        from: dagu@company.com
        subject: "${DAG_NAME} failed"
        message: |
          Run ID: ${DAG_RUN_ID}
          Logs: ${DAG_RUN_LOG_FILE}

Run a Follow-up DAG

yaml
handlerOn:
  success:
    run: sync-reporting
    params: |
      parent_run_id: ${DAG_RUN_ID}

Guaranteed Cleanup

yaml
handlerOn:
  exit:
    command: |
      find /tmp/${DAG_RUN_ID} -maxdepth 1 -type f -delete

For the complete schema, refer to the YAML specification. Combine handlers with the techniques from Error Handling and Data & Variables to build robust workflow lifecycles.

Released under the MIT License.