Airflow module
Lesson 6
When tasks fail
Read task logs, set retries, clear a failed run, and fix a DAG that never appears.
beginner30 minRun on your machine
What you will be able to do
- Trigger a failing task and read its log in the UI
- Add retries and clear a task to rerun
- Use dag-processor logs when a DAG file does not show up
Why this matters for data work
Orchestration is mostly failure handling. The happy path is a green graph. The job is: see red, read the log, decide retry vs skip vs fix the file, leave an audit trail. Airflow is useful because that loop has names.
Concepts
Task states — queued, running, success, failed, upstream_failed, skipped, up_for_retry.
Retries — @task(retries=2) or retries= on an operator. A flake (network blip) should retry; a KeyError in your code should not retry five times hoping the key appears.
Logs — UI task log, and files under ~/dcubes/airflow-lab/logs. Start in the UI.
Clear — from the grid or graph, clear a failed task (and optionally downstream) to run it again with the same DAG run. You do not always need a new Trigger.
Import errors — if the DAG processor cannot import the file, the DAG is absent from the list (or listed under import errors). This is not a failed task. It is a broken module.
OOM — Docker Desktop out of memory kills containers. Scheduler health goes red. Free RAM; this is not a Python traceback.
Practice on your machine
Write a DAG that fails on purpose, then fix it.
cd ~/dcubes/airflow-lab
cat > dags/fail_then_fix.py << 'EOF'
from datetime import datetime
from airflow.sdk import dag, task
@dag(
schedule=None,
start_date=datetime(2024, 1, 1),
catchup=False,
tags=["dcubes"],
)
def fail_then_fix():
@task(retries=0)
def boom() -> None:
raise ValueError("planted failure — you will fix this")
boom()
fail_then_fix()
EOF
Wait for fail_then_fix. Unpause, trigger. boom should go red.
Open Logs. You should see ValueError: planted failure — you will fix this.
Now fix the file:
cd ~/dcubes/airflow-lab
cat > dags/fail_then_fix.py << 'EOF'
from datetime import datetime
from airflow.sdk import dag, task
@dag(
schedule=None,
start_date=datetime(2024, 1, 1),
catchup=False,
tags=["dcubes"],
)
def fail_then_fix():
@task(retries=0)
def boom() -> None:
print("all good")
boom()
fail_then_fix()
EOF
Wait a few seconds for parse. In the UI, clear the failed boom task on the existing run (or Trigger a new run). It should succeed and print all good.
Import error drill
Break the file:
cd ~/dcubes/airflow-lab
echo "this is not python" > dags/fail_then_fix.py
Wait, then:
docker compose logs airflow-dag-processor --tail 30
You want a traceback that names fail_then_fix.py. Restore the working file from the “all good” block above (or delete the DAG if you are done with it):
rm ~/dcubes/airflow-lab/dags/fail_then_fix.py
What you should see
- A red task with a readable ValueError.
- After the fix, a green task on clear or a new run.
- Processor logs that name a broken file when the DAG vanishes.
Common mistakes
- Re-triggering instead of reading the log. The error is already there.
- retries=5 on a syntax bug. You wait. Fix the code.
- Ignoring processor logs. “DAG not in the UI” is parse, not schedule.
- Full disk / no RAM.
docker compose psunhealthy.docker compose downother labs; give Desktop more memory.
Next
Capstone: First Airflow shift