This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new f14247a5938 Add a general debugging guide to the troubleshooting doc 
(#71457)
f14247a5938 is described below

commit f14247a5938a8ad34bb7627a05c2daff9096f8ff
Author: Baha Bouali <[email protected]>
AuthorDate: Thu Nov 5 14:04:46 2026 +0100

    Add a general debugging guide to the troubleshooting doc (#71457)
    
    * Add a general debugging guide to the troubleshooting doc
    
    * add line break
    
    * Improve clarity of Airflow troubleshooting guide
    
    Refactor troubleshooting documentation for clarity and consistency.
    
    * Fix typos in troubleshooting.rst
    
    from British Spelling to American Spelling
    
    * correct troubleshooting guide based on new airflow 3
    
    * Include the triggerer in the components that use the metadata database
    
    The triggerer's main process connects to the metadata database as well, so 
a reader debugging a triggerer would otherwise conclude it does not.
    
    Generated-by: Claude Opus 5
    
    ---------
    
    Co-authored-by: Jarek Potiuk <[email protected]>
---
 airflow-core/docs/troubleshooting.rst | 129 ++++++++++++++++++++++++++++++++++
 docs/spelling_wordlist.txt            |   2 +
 2 files changed, 131 insertions(+)

diff --git a/airflow-core/docs/troubleshooting.rst 
b/airflow-core/docs/troubleshooting.rst
index 368d6c786f6..5ad38ed15df 100644
--- a/airflow-core/docs/troubleshooting.rst
+++ b/airflow-core/docs/troubleshooting.rst
@@ -20,6 +20,135 @@
 Troubleshooting
 ===============
 
+How to debug your Airflow deployment
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The sections below walk through Airflow deployment issues using David A. 
Wheeler's writeup
+of Agans' nine rules of debugging [1]_, with an Airflow-specific action for 
each rule. They are
+written as a general starting point; for the specific known failure modes 
already documented,
+see `Obscure task failures`_ below.
+
+Understand the system
+----------------------
+
+A minimal Airflow deployment is made up of a *scheduler*, a *Dag processor*, a 
*Dag bundle*,
+an *API server*, and a *metadata database*; larger deployments add *workers* 
and a *triggerer*.
+Each component can fail independently, and Airflow 3 removed the standalone 
webserver process
+in favor of the API server, and moved Dag parsing out of the scheduler and 
into its own
+*Dag processor* process. Before debugging a specific failure, know which of 
these components
+is involved. See :doc:`/core-concepts/overview` for the full component 
breakdown.
+
+Make it fail
+------------
+
+Reproduce the failure outside of the full scheduling loop before you start 
changing things:
+
+- ``airflow tasks test <dag_id> <task_id>`` runs a single task instance 
without checking its
+  dependencies. Leave out the optional ``logical_date_or_run_id`` argument, so 
the command creates
+  a throw-away Dag run and deletes it afterwards. If that argument matches an 
existing Dag run, the
+  command runs that run's real task instance and records the result in the 
database, overwriting
+  the task instance's state.
+- ``airflow dags test <dag_id> [logical_date]`` runs one full Dag run locally, 
without the
+  scheduler.
+
+Both commands run in your current process, so you can also attach a debugger 
to them; see
+:doc:`/core-concepts/debug` for running a Dag under ``pdb`` or an IDE debugger.
+
+``airflow tasks test`` reads the serialized Dag from the metadata database, so 
it only works for a
+Dag the Dag processor has already parsed. If the Dag fails to parse, start with
+``airflow dags list-import-errors`` instead.
+
+Quit thinking and look
+-----------------------
+
+Read the actual task log before guessing at a cause. Task logs are written on 
the worker that ran
+the task, under :ref:`logging.base_log_folder 
<config:logging__base_log_folder>` (by default
+``$AIRFLOW_HOME/logs/``), using the path
+``dag_id=<dag_id>/run_id=<run_id>/task_id=<task_id>/attempt=<n>.log`` (add a
+``map_index=<n>/`` segment for mapped tasks). The path is controlled by the
+:ref:`logging.log_filename_template <config:logging__log_filename_template>` 
setting, so check
+both settings if logs aren't where you expect them. If
+:doc:`remote logging 
</administration-and-deployment/logging-monitoring/logging-tasks>` is
+enabled, the log may only be available in the remote store. ``airflow tasks 
state <dag_id>
+<task_id> <logical_date_or_run_id>`` will confirm the recorded state of a task 
instance before you
+go looking at logs at all.
+
+Divide and conquer
+-------------------
+
+Narrow the failure down to a single component before digging further. These 
commands need access
+to the metadata database, so run them from a host that has it, such as the 
scheduler or API
+server, not from a worker:
+
+- ``airflow dags list-import-errors`` shows Dags the *Dag processor* failed to 
parse. A Dag
+  that fails to parse is a Dag-processor problem, not a scheduler problem, in 
Airflow 3.
+- ``airflow db check`` confirms the metadata database is reachable from the 
host you run it on.
+  Only the scheduler, Dag processor, triggerer, and API server connect to the 
metadata database.
+  Workers talk to the API server at
+  :ref:`core.execution_api_server_url <config:core__execution_api_server_url>` 
instead, so for a
+  worker, check that it can reach that URL (for example,
+  ``curl http://<api-server>:8080/execution/health`` should return 
``{"status": "healthy"}``).
+- ``airflow tasks failed-deps <dag_id> <task_id> <logical_date_or_run_id>`` 
shows the unmet
+  dependencies that are keeping the scheduler from queuing a task instance.
+
+To check the health of each component, see
+:doc:`/administration-and-deployment/logging-monitoring/check-health`, which 
covers the
+``/api/v2/monitor/health`` endpoint and ``airflow jobs check``.
+
+Change one thing at a time
+---------------------------
+
+When testing a fix, change a single variable and re-run ``airflow tasks test 
<dag_id> <task_id>``
+(without a run ID, so each attempt gets its own throw-away Dag run) or 
``airflow dags test``
+before layering on the next change. ``airflow config get-value <section> 
<option>`` prints the
+effective value of a single configuration option, so you can confirm exactly 
what changed between
+runs instead of assuming.
+
+Keep an audit trail
+--------------------
+
+Record what you tried and what happened. ``airflow version`` records the exact 
version you were
+running; ``airflow dags show <dag_id> --save graph.png`` saves the task 
dependency graph for a
+Dag (this needs Graphviz installed: both the system package and the 
``graphviz`` Python
+package); ``airflow tasks states-for-dag-run <dag_id> 
<logical_date_or_run_id>`` records the
+state of every task instance in a run. Keeping these alongside your notes 
makes it possible to
+tell later whether a change actually affected behavior.
+
+Check the plug
+---------------
+
+Before debugging further, check the things that are easy to overlook:
+
+- Is the Dag paused? ``airflow dags list`` includes an ``is_paused`` column.
+- Can the component you're debugging actually reach what it depends on? For 
the scheduler, Dag
+  processor, and API server, that's the metadata database (``airflow db 
check``). For a worker,
+  it's the API server at
+  :ref:`core.execution_api_server_url <config:core__execution_api_server_url>`.
+- Are you confusing the Dag's *logical date* with wall-clock time? A Dag run's 
``logical_date``
+  is not the time the run actually started.
+
+Get a fresh view
+-----------------
+
+When asking someone else to look at a failure, give them something 
reproducible rather than a
+description: the exact command you ran, the ``airflow version`` output, the 
relevant log excerpt,
+and, if it's a Dag-structure question, a saved graph from ``airflow dags 
show``. A vague
+description is much harder for a second set of eyes to act on than a small, 
self-contained
+reproduction.
+
+If you didn't fix it, it ain't fixed
+-------------------------------------
+
+Confirm the fix by reproducing the original failure the same way you made it 
fail in the first
+place -- rerun the same ``airflow tasks test`` (without a run ID) or ``airflow 
dags test``
+invocation -- rather than assuming a code change or a passing unit test alone 
means the deployment
+issue is resolved. If the original failure was intermittent, re-run it more 
than once before
+calling it fixed.
+
+.. [1] David A. Wheeler, `Debugging: nine indispensable rules for finding even 
the most
+   elusive software and hardware problems 
<https://dwheeler.com/essays/debugging-agans.html>`__
+   (2004), summarizing David J. Agans' nine rules of debugging.
+
 Obscure task failures
 ^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 702198549b6..74a4dd355b3 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -27,6 +27,7 @@ adobjects
 AdsInsights
 adsinsights
 afterall
+Agans
 agentcore
 AgentDetails
 agentic
@@ -2003,6 +2004,7 @@ webservers
 webViewLink
 Werkzeug
 werkzeug
+Wheeler
 whitespace
 whl
 wildcarded

Reply via email to