This is an automated email from the ASF dual-hosted git repository. vatsrahul1001 pushed a commit to branch v3-4-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit d4cab4cce4e475205a02047dcd72e9c2ead98fb9 Author: Rahul Vats <[email protected]> AuthorDate: Tue Oct 13 16:23:07 2026 +0530 Add 3.4.0 release notes --- RELEASE_NOTES.rst | 795 ++++++++++++++++++++++ airflow-core/newsfragments/58543.feature.rst | 1 - airflow-core/newsfragments/62501.bugfix.rst | 1 - airflow-core/newsfragments/63491.significant.rst | 60 -- airflow-core/newsfragments/66350.bugfix.rst | 1 - airflow-core/newsfragments/66633.bugfix.rst | 1 - airflow-core/newsfragments/67372.bugfix.rst | 1 - airflow-core/newsfragments/67927.feature.rst | 1 - airflow-core/newsfragments/68314.improvement.rst | 1 - airflow-core/newsfragments/68496.significant.rst | 32 - airflow-core/newsfragments/68517.significant.rst | 14 - airflow-core/newsfragments/68521.feature.rst | 1 - airflow-core/newsfragments/68548.feature.rst | 1 - airflow-core/newsfragments/68741.bugfix.rst | 1 - airflow-core/newsfragments/68760.significant.rst | 11 - airflow-core/newsfragments/68791.improvement.rst | 1 - airflow-core/newsfragments/68890.significant.rst | 6 - airflow-core/newsfragments/68954.bugfix.rst | 1 - airflow-core/newsfragments/69075.bugfix.rst | 1 - airflow-core/newsfragments/69469.significant.rst | 26 - airflow-core/newsfragments/69675.bugfix.rst | 1 - airflow-core/newsfragments/69768.feature.rst | 1 - airflow-core/newsfragments/69790.feature.rst | 1 - airflow-core/newsfragments/69792.bugfix.rst | 1 - airflow-core/newsfragments/70013.feature.rst | 1 - airflow-core/newsfragments/70089.bugfix.rst | 1 - airflow-core/newsfragments/70154.significant.rst | 1 - airflow-core/newsfragments/70759.significant.rst | 24 - airflow-core/newsfragments/70838.feature.rst | 1 - airflow-core/newsfragments/70886.significant.rst | 19 - airflow-core/newsfragments/70947.feature.rst | 1 - airflow-core/newsfragments/70972.significant.rst | 13 - airflow-core/newsfragments/71192.significant.rst | 12 - airflow-core/newsfragments/71251.bugfix.rst | 1 - airflow-core/newsfragments/71729.improvement.rst | 1 - airflow-core/newsfragments/71957.improvement.rst | 1 - airflow-core/newsfragments/71968.bugfix.rst | 1 - airflow-core/newsfragments/71990.bugfix.rst | 1 - airflow-core/newsfragments/72036.feature.rst | 1 - airflow-core/newsfragments/72100.significant.rst | 59 -- airflow-core/newsfragments/72164.significant.rst | 23 - airflow-core/newsfragments/72407.significant.rst | 23 - airflow-core/newsfragments/72494.feature.rst | 1 - airflow-core/newsfragments/72682.feature.rst | 1 - airflow-core/newsfragments/72896.significant.rst | 16 - airflow-core/newsfragments/73054.significant.rst | 13 - airflow-core/newsfragments/73244.significant.rst | 22 - airflow-core/newsfragments/73294.significant.rst | 14 - airflow-core/newsfragments/73328.significant.rst | 6 - airflow-core/newsfragments/73554.significant.rst | 24 - airflow-core/newsfragments/73746.significant.rst | 22 - airflow-core/newsfragments/73806.improvement.rst | 1 - airflow-core/newsfragments/73970.significant.rst | 5 - airflow-core/newsfragments/74151.significant.rst | 17 - airflow-core/newsfragments/74278.feature.rst | 1 - airflow-core/newsfragments/74499.bugfix.rst | 1 - airflow-core/newsfragments/task-loops.feature.rst | 1 - 57 files changed, 795 insertions(+), 495 deletions(-) diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 90ffa8a8e62..48169742c44 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -24,6 +24,778 @@ .. towncrier release notes start +Airflow 3.4.0 (2026-11-02) +-------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Task Loops (#73005, #74222, #74274, #74275) +""""""""""""""""""""""""""""""""""""""""""" + +Airflow 3.4.0 introduces Task Loops (AIP-111): a decorated task group can be repeated a number of +times decided at runtime using ``.loop()``. A conditional loop works like a ``do ... while`` loop - +the body runs at least once and an ``until`` condition decides when to stop, bounded by +``max_iterations``. Each iteration can use the previous iteration's result and iterations run one +after another (tasks within an iteration can still run in parallel). Retried attempts are kept +under a per-attempt UUID so each iteration's data is preserved and can be cleared selectively. + +For detailed usage instructions, see :doc:`/authoring-and-scheduling/loops`. + +Dag Importer for non-Python Dags (#72369, #73728, #73853, #74020, #74084, #74333, #74586) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Airflow 3.4.0 can author an entire Dag - schedule, tasks, and dependencies - in a language other +than Python. AIP-85 adds a pluggable Dag Importer in the Task SDK that teaches the Dag processor to +recognize source formats beyond ``.py``: each format registers an importer, the processor runs the +matching language runtime, and the resulting Dags surface in Airflow like Python Dags. The formats +that land on it are the TypeScript, Go, and Java language SDKs and a native YAML Dag format (a +``.yaml`` file with a ``$schema`` marker, validated against a schema and built into real operators, +with explicit templating). The Dag Importer framework and the language SDKs are experimental in 3.4 +and their APIs may change. + +For detailed usage instructions, see :doc:`/administration-and-deployment/dag-importers`. + +Unify executor workload queues under ``BaseExecutor.executor_queues`` (#63491) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Executor workload state is now stored on the unified ``BaseExecutor.executor_queues`` mapping keyed +by ``WorkloadType`` and scheduled through ``trigger_workloads``. The previous per-type attributes +and entrypoints (``queued_tasks``, ``queued_callbacks``, ``supports_callbacks``, ``trigger_tasks``, +``order_queued_tasks_by_priority``) and the Airflow 3.3 connection-test surface are folded into +this mapping and kept as backward-compatible shims that emit ``RemovedInAirflow4Warning`` (to be +removed in Airflow 4.0). Out-of-tree executors should declare ``supported_workload_types`` and +implement ``trigger_workloads``. Connection tests are now admitted under the same per-heartbeat +budget as tasks and prioritized ahead of them. See +`#63491 <https://github.com/apache/airflow/pull/63491>`_ for the full migration guide. + +psycopg3 is now the default Postgres driver (#68496) +"""""""""""""""""""""""""""""""""""""""""""""""""""" + +psycopg3 (``psycopg``) is now the default driver for the metadata database, for both the sync and +the async engine, replacing psycopg2 and asyncpg. A bare ``postgresql://`` (or a legacy +``postgres://`` / ``postgres+psycopg2://``) ``sql_alchemy_conn`` is rewritten to +``postgresql+psycopg://``, and the derived async URL uses ``postgresql+psycopg_async://`` when +psycopg3 is installed (falling back to asyncpg otherwise). Airflow also disables psycopg3's +server-side statement preparation (``prepare_threshold = None``) so the metadata database works out +of the box behind transaction-mode PgBouncer, the recommended production setup. To keep psycopg2 or +asyncpg, install the ``apache-airflow-providers-postgres[psycopg2]`` / ``[asyncpg]`` extra and +configure the connection explicitly; see #68496 and #69469 for details, including how to re-enable +statement preparation. + +Asset-triggered Dags create one run per event by default (#68517) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Single-asset schedules and asset OR expressions now create one Dag run per event instead of +consuming all queued events in one run. This also applies to ``AssetOrTimeSchedule`` and +``PartitionedAssetTimetable``. + +To retain batching, set ``batch_asset_events=True`` on the timetable or enable ``[scheduler] +batch_asset_events`` and reparse the affected Dags. Already serialized timetables without this +option retain their previous batching behavior until reparsed. + +Schedules requiring several events, including ``schedule=[a, b]``, asset AND expressions, and +partitioned timetables using ``RollupMapper``, continue to batch by default. Explicitly setting +``batch_asset_events=False`` for these schedules raises a timetable validation error. + +Custom graph colors return via ``ui_color`` and ``ui_fgcolor`` (#68760) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The ``ui_color`` and ``ui_fgcolor`` attributes on operators and TaskGroups color the graph view +again -- the node fill from ``ui_color`` and the operator label from ``ui_fgcolor``, as they did in +Airflow 2. They were silently ignored since Airflow 3.0. + +The value can be a raw color (a hex code like ``#e8b7e4`` or a CSS name) or a Chakra theme token -- +a palette token such as ``blue.500`` or a semantic token such as ``brand.solid`` that adapts to +light and dark mode (including tokens added through custom UI theming); a token resolves through a +theme-controlled CSS variable. The node border keeps reflecting the task-instance run state; the +custom color is applied to the fill and label only. + +``validate_key`` now raises ``ValueError`` instead of ``AirflowException`` (#68890) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The ``airflow.utils.helpers.validate_key`` utility now raises ``ValueError`` instead of +``AirflowException`` when an invalid key is provided (for example an invalid format or a +length-limit violation). + +The deprecated ``Dataset`` alias has been removed from the ``airflow`` module (#70154) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Use ``Asset`` from ``airflow.sdk`` instead. + +Audit log rows not tied to a Dag now require the ``AUDIT_LOGS_ALL`` view (#70759) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Rows in the audit log whose ``dag_id`` is ``NULL`` record operations that are not tied to a Dag, +such as Connection, Variable and Pool changes. They were returned to any caller that could read +event logs at all, because there is no per-Dag key to authorize them on and both read paths fell +back to a Dag-level audit log check. + +They are now gated on a dedicated ``AccessView.AUDIT_LOGS_ALL``, in the same way +``AccessView.IMPORT_ERRORS_ALL`` gates import errors for files with no registered Dag. Rows bound +to a Dag keep their existing per-Dag check. + +- ``GET /eventLogs`` no longer returns rows with a ``NULL`` ``dag_id`` to callers without the new + view, and excludes them from ``total_entries`` and pagination. ``GET /eventLogs/{event_log_id}`` + returns ``403`` for such a row. An id matching no row still returns ``404``. +- With the simple auth manager the view is granted to the ``ADMIN`` role only. With the FAB auth + manager it maps to a new ``All Audit Logs`` resource, which ships in the ``Admin`` role; custom + roles that need to read these rows must be granted ``All Audit Logs.can_read`` explicitly. +- An auth manager that cannot map a requested ``AccessView`` now denies that view and emits a + ``UserWarning`` instead of raising ``KeyError``. This affects auth managers older than the core + they run against, which previously failed the request with a server error. + +Team names must now be lower case, and cannot contain two consecutive underscores (#70886) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``airflow teams create`` and ``airflow teams sync`` now accept only names matching +``(?!.*__)[a-z0-9_-]{3,50}`` -- lower case letters, digits, hyphens and single underscores. Upper +case letters and ``__`` were previously accepted. + +A team name is embedded in the ``AIRFLOW_CONN__<TEAM>___<ID>`` environment variable namespace that +holds team scoped secrets, and the backend upper-cases the name when it builds that variable. +``data_eng`` and ``Data_Eng`` therefore resolved a single namespace between them, and a name +containing ``___`` could not be told apart from the separator. + +``airflow db migrate`` lower-cases every stored team name, moving that team's Dag bundles, +Connections, Variables, Pools and Triggers with it. Two stored names that differ only in case would +collapse onto one row and silently merge two teams, so migration refuses to start while any such +pair exists -- rename all but one first. Names that stay invalid for another reason, such as +containing ``__``, are migrated as they are; they keep working, but ``airflow teams sync`` exits +non-zero until they are renamed. + +Changes to how pending asset events trigger Dag runs (#70972) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Deleting asset event records with ``airflow db clean`` now also removes any asset events that are +still pending for a downstream Dag. This mainly affects Dags waiting on a multi-asset condition, +where a pending event can be purged before the condition is met. Deleting an asset event now +consistently means it will not trigger a run; previously such a pending trigger could still fire +after the event had been purged. + +Relatedly, an asset event that was queued for a Dag while it was scheduled on that asset is still +used to trigger the run, and appears among the run's triggering events, even if the asset is later +removed from the Dag's schedule. Previously, they were silently dropped. + +Callbacks now redeem a single-use token before they run (#71192) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +A worker now redeems a callback's single-use token with the API server (``PATCH +/execution/callbacks/{callback_id}/run``) before importing and running the callback. Redeeming the +token moves the callback from queued to running and swaps it for a short-lived execution-scoped +token. Before this change a callback ran without the worker making any authenticated call, so the +token minted for it was never checked. + +Because the token is single-use, a redelivered or replayed message that reaches a callback that is +already running or finished is refused rather than run again. A worker on 3.4 needs an API server +that serves this endpoint; a worker talking to an older API server negotiates the API version and +behaves as though the endpoint is not there. + +Clearing a task now discards its task state store entries by default (#72100) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Clearing a task instance now discards its ``task_state_store`` entries, so the next attempt starts +from the beginning instead of resuming from a checkpoint or reconnecting to an external job +recorded by the cleared attempt. Retries are unaffected and keep task state as before. This applies +to clearing individual task instances (the clear endpoint/dialog and ``airflowctl tasks``/``dags +clear``); clearing a whole Dag run still keeps task state (tracked in +`#72929 <https://github.com/apache/airflow/issues/72929>`_). To preserve the old behaviour, pass +``keep_task_state=True`` (or tick "keep task state" in the clear dialog; a per-browser default is +available under Settings > Clearing). Note a task-instance clear now also deletes +``task_state_store`` rows for that task instance. + +``[core] execute_tasks_new_python_interpreter`` now applies to Airflow 3 task processes (#72164) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +On Airflow 3 the option had no effect on task execution (only the Edge worker read it). When set to +``True``, the task supervisor now ``exec``\ s a fresh interpreter right after forking the task +process, which prevents the fork from inheriting a lock held by a supervisor thread (a permanent +hang at the task's first TLS call). Deployments that kept the option ``True`` from Airflow 2 get +this behaviour, and its per-task interpreter start-up cost, on upgrade without further action; set +it to ``False`` to keep bare fork. The task process reads the global value, so a team-scoped Edge +setting alone does not turn it on. Edge workers with the option ``True`` already start a fresh +interpreter for the supervisor and will now start a second one for the task. The Dag processor, the +triggerer and task callbacks (which the callback supervisor runs from a closure that cannot be +named for an exec'd child) are not affected and keep bare fork. + +Gracefully pause Dags by draining active runs (#72407, #73225, #73055, #73763) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Airflow now supports a ``draining`` scheduling state for Dags. Draining stops the scheduler from +creating new scheduled or asset-triggered Dag runs while allowing already queued and running Dag +runs to continue. Explicitly triggered runs remain allowed. + +After outstanding Dag runs finish, the Dag automatically transitions to ``paused``. Users can +cancel draining to return the Dag to ``active``. + +Manual runs, backfills and asset materializations on a paused Dag can drain the Dag instead of +unpausing it: choose **Drain** in the UI, or set ``drain_dag`` in the REST API request. Draining +lets unfinished runs of the Dag start or resume, except those held by paused backfills, creates no +scheduled runs, and pauses the Dag again once all unfinished runs finish. Paused backfills remain +paused and must be resumed for their runs to finish and draining to complete. + +The UI, REST API, and ``airflowctl`` expose the ``active``, ``draining``, and ``paused`` scheduling +states, and the Dags list can pause, drain, or unpause several selected Dags at once. Existing +``is_paused`` API usage remains supported; use ``scheduling_state`` when the draining state must be +selected or reported explicitly. + +Reparsing a file with no registered Dag now requires the ``REPARSE_ALL`` view (#72896) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +A file that failed to import before defining any Dag has no per-Dag key to authorize a reparse +against, so ``PUT /parseDagFile/{file_token}`` previously returned ``404`` for it. Reparsing such a +file is now gated on a dedicated ``AccessView.REPARSE_ALL`` -- a write action of its own, distinct +from the permission to view import errors -- and the Dag import errors modal gains a reparse action +for these files. + +- ``PUT /parseDagFile/{file_token}`` for a file with no registered Dag authorizes against + ``REPARSE_ALL`` and returns ``403`` when the caller lacks it, instead of ``404``. A file that has + a registered Dag keeps its existing per-Dag ``can_edit`` check. +- With the simple auth manager the view is granted to the ``ADMIN`` role only. With the FAB auth + manager it maps to a new ``All Reparses`` resource, which ships in the ``Admin`` role; custom + roles that need to reparse such files must be granted ``All Reparses.can_read`` explicitly. + +Removed the ``--file-io`` option from the ``airflow info`` command (#73054) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``--file-io`` uploaded the report to file.io and printed a shareable link. file.io no longer +accepts anonymous uploads, so the option could not succeed; it also ended in an unhandled traceback +rather than reporting the failure. + +Redirect the output instead:: + + airflow info --anonymize > airflow-info.txt + +Note that ``--file-io`` applied ``--anonymize`` implicitly. Pass ``--anonymize`` explicitly when +sharing a report: plain ``airflow info`` prints connection strings, including passwords, in +cleartext. + +Task heartbeats are no longer retried by ``[workers] execution_api_retries`` (#73244) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Heartbeats had two overlapping retry mechanisms: the Task SDK API client retried every request, +including heartbeats, and the supervisor separately counted consecutive heartbeat failures against +``[workers] max_failed_heartbeats``. The client retries also had the unwanted side-effect of +blocking the supervisor's monitor loop while it backed off, so during an API server outage the +supervisor would be delayed forwarding task logs and/or noticing that the task subprocess had +exited. + +Heartbeat retries are now governed solely by ``max_failed_heartbeats``, whose default has been +adjusted from ``3`` to ``30`` to keep roughly the same tolerance for an unreachable API server as +the two mechanisms combined gave before. + +If you have set ``[workers] max_failed_heartbeats`` explicitly, you may wish reconsider value you +have chosen. It is now the whole retry budget: with the default ``[workers] +min_heartbeat_interval`` of 5 seconds, the worker tolerates roughly ``5 * max_failed_heartbeats`` +seconds of API unavailability before terminating a running task. You should likely keep the +resulting value below any configured ``[scheduler] task_instance_heartbeat_timeout`` (default 300 +seconds). + +Deadline alert callbacks validated at parse time; numeric intervals deprecated (#73294) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``DeadlineAlert`` now refuses a ``callback`` that is not exactly ``AsyncCallback`` or +``SyncCallback``, so a subclass fails when the Dag is parsed rather than when the scheduler reads +it back. The scheduler decodes stored callbacks by exact class name so no class named by a Dag +author is imported or instantiated there, which means a subclass could be written and then never +read. + +Passing a number as the ``interval`` is deprecated and now emits ``RemovedInAirflow4Warning``. It +is still accepted and taken as a count of seconds, but the supported types are ``timedelta`` and +``VariableInterval``. A ``timedelta`` subclass such as ``pendulum.duration(...)`` is accepted and +normalized to a plain ``timedelta``, where previously it passed validation and then failed during +serialization. ``interval=True`` is refused, because ``bool`` is an ``int`` subclass and would +otherwise be taken as one second. + +The ``POST /assets/{asset_id}/materialize`` endpoint now requires a JSON request body (#73328) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Previously a request with no body was accepted and the asset was materialized with default values. +The endpoint now requires an explicit JSON body, consistent with the other mutating endpoints: a +request without a body is rejected with ``422``, and an empty HTML form is not a valid input +anymore. All body fields remain optional, so an empty object (``{}``) is a valid body. + +TaskInstance try numbers now increase before the next try starts (#73554) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. note:: + + If you have any external systems that look at task logs or TI state for an up-for-retry TI, you + will need to be aware of this change and update your code. + + For example, if you made a request to ``GET + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}`` expecting to get info about + the failed try, you will now need to look at ``GET + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/tries/{try_number - 1}`` + +When a task is up_for_retry, try_number now identifies the upcoming try. To retrieve the try that +failed, request ``/tries/{try_number - 1}``. The UI shows the pending try and provides a link to +the previous try's logs. + +Airflow now allocates a task instance's UUID and try number together immutably so they consistently +identify the same try. + +Previously when a task entered the retry cooldown period, it would be given a new UUID, but keep on +try number N and have the state of UP_FOR_RETRY until that period was up (at which point that try +would be marked FAILED and the try number incremented). Instead, the failed try is immediately +marked with state of FAILED, and a new try created in state UP_FOR_RETRY. + +Deprecate cyclic TaskGroup dependencies (#73746) +"""""""""""""""""""""""""""""""""""""""""""""""" + +A Dag whose TaskGroups depend on each other in a cycle, when each TaskGroup is treated as a single +unit, now issues a ``TaskGroupCycleDeprecationWarning`` at parse time and shows a Dag warning in +the UI that names the TaskGroups and tasks involved. These Dags still parse and run, because their +task dependencies are acyclic, but Airflow 3.5 is planned to reject them at parse time. + +A dependency into or out of any task in a TaskGroup counts as a dependency of the whole group, so a +path that leaves a TaskGroup and comes back into it is a cycle. For example, ``a >> bridge >> b``, +with ``a`` and ``b`` in the same TaskGroup and ``bridge`` outside it, makes the group depend on +``bridge`` and ``bridge`` depend on the group, even if ``a >> b`` is also set. + +- Move tasks between TaskGroups, or out of them, so that each group depends on the others in one + direction only. In the example above, move ``bridge`` into the group, or move ``b`` out of it. +- To catch these Dags in CI, run your Dag tests with ``-W + error::airflow.sdk.exceptions.TaskGroupCycleDeprecationWarning``. The check runs when a Dag is + added to a ``DagBag``, so only tests that load your Dags into a ``DagBag`` and assert there are + no import errors catch them; a test that only imports a Dag file does not. + +See "Cyclic TaskGroup dependencies" in the Dags documentation. + +Language SDK coordinators load task handlers from a Dag bundle (#73970) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The experimental ``jars_root`` (Java) and ``executables_root`` (Go) coordinator kwargs are removed. +Put the artifacts in a Dag bundle registered in ``[dag_processor] dag_bundle_config_list`` and set +``task_handler_bundle_name`` in the coordinator's ``kwargs``, or leave it unset to use the task's +own Dag bundle. A config that still sets a removed kwarg fails with ``Cannot instantiate +coordinator '<key>'``. + +Support for Python 3.10 has been removed (#74151) +""""""""""""""""""""""""""""""""""""""""""""""""" + +Airflow now requires Python 3.11 or newer. Python 3.10 reaches its end of life in October 2026, and +Airflow drops support for a Python version in ``main`` as soon as it reaches end of life. The +``apache-airflow`` distribution, the Task SDK, ``airflowctl`` and all providers released from +``main`` declare ``requires-python = ">=3.11"``. + +New Features +^^^^^^^^^^^^ + +- Add dag version lookup on get task endpoint (#74365) +- Add Logical Date column to the Runs table (#74340) +- UI: Add a Dag Run ID column to the Task Instances list (#74316) +- UI: Add duration filter to DAG Backfills tab (#74202) +- Add a user setting for the default search match mode (#74021) +- Add URL param support to calendar view (#73237) (#73762) +- UI: Add team filter to Human-in-the-loop task instances listing (#73726) +- add bundle_name tags to missing dag processor metrics (#73717) +- Add fab-oauth meta-package extra (#73565) +- Allow a Job to be associated with several teams (#73561) +- Add ``ChainRetryPolicy`` to compose retry policies in order (#73508) +- Add task state store API to the Java SDK (#73464) +- UI: Add a default preference for expanded task groups (#73429) +- Add task state store support to the Go SDK task client (#73420) +- UI: Add team column and filter to the jobs list (#73295) +- Add SetVariable and DeleteVariable to the Go SDK task client (#73084) +- Allow template-field copies into StartTriggerArgs in operator __init__ (#73040) +- Allow plugins to add or override UI translations (#72648) +- Support multi-column sort in the Dags list table (#72558) +- Add dry-run mode to teams sync (#72494) +- Add Has Events filter to Assets search (#72460) +- UI: Add 'Mark as Skipped' option to Task Instance actions (#72425) +- UI: Add toggle to show or hide log levels in task logs (#72363) +- Add async Variable methods (aget, aset, adelete, akeys) (#72329) +- UI: Add team column and filter to the XComs list (#72158) +- UI: Add team column and filter to the deadlines list (#72060) +- Add integrity metadata to TypeScript bundles (#72046) +- Multi-Team: Add teams inspect CLI command to display team resources (#72036) +- ``is_scheduled`` REST API parameter (#72029) +- Allow Variable.get to reuse the caller's database session (#71968) +- UI: Add team column and filter to the audit log (#71916) +- Support a regex for the API's CORS allowed origins (#71778) +- CLI: Add --limit flag to airflow dags list-runs (#71729) +- Add SSL cipher list option to the api server (#71645) +- Add ConnectionNotFoundError to the TypeScript SDK (#71375) +- Add preset filters to the Dags list page (#71368) +- Add Dag ID filtering to Assets search (#70971) +- Allow filtering the Dag runs list by Dag tags (#70861) +- Support DagBundle based deployment for Coordinator (#70805) +- Add a user settings page for cross-page UI defaults (#70687) +- Support a Unix Domain Socket for the metrics clients (#70517) +- UI: Add a time-window scope to the Dags list run state filter (#70470) +- UI: Add a slowest tasks chart to the Dag Overview (#70305) +- Add task log message when the Execution API is unreachable (#70290) +- UI: Add team column and filter to Dag Run and Task Instance lists (#70241) +- Support schema-qualified table names in db clean (#70147) +- UI: Add team column and filter to Dag list page (#70028) +- Add React plugin support to Dag and task overviews (#69992) +- Add Asset Tab plugin (#69986) +- Add serialized Dag version diff engine (#69864) +- UI: Add timetable type filter to Dag list (#69728) +- Allow embedding a Dag run in an external trace via run conf (#69633) +- Add deadlines to Calendar Tab (#69559) +- Add team_name attribute to plugins for multi-team (#69502) +- Add exact-match uri filter to GET /assets endpoint (#69489) +- Add runtime DagRun note updates (#69403) +- Add airflowctl tasks failed-deps command (#69397) +- Add indexes on serialized_dag and dag_code (#69391) +- Add airflowctl tasks states-for-dag-run command (#69366) +- Add airflowctl tasks clear command (#69320) +- Add streaming task log support to BaseExecutor and FileTaskHandler (#69299) +- Add airflow-ts-pack bundle build tool for TypeScript SDK (#69295) +- UI: Allow scoping plugin tabs to specific Dags and tasks (#69148) +- Add metrics for how often a dag gets serialised. (#68906) +- Allow forcing trace head-sampling per DAG run via conf (#68860) +- Add Calendar Deadlines API and Data Models (#68604) +- Add NodeCoordinator (#68548) +- Add async task store accessors for async tasks (#68232) +- Add scheduler observability metrics (#68068) +- Add extra field filtering for asset events (#64611) +- Add partition_key and partition_key_regexp_pattern filters for asset events (#64610) +- Add REST API metrics (#64523) +- Add ``AssetAndTimeSchedule`` timetable (#58543) + +Bug Fixes +^^^^^^^^^ + +- Fix 400 and 500s on POST /connections/defaults in multi-team mode (#74615) +- Keep the scheduler running when a queued run's Dag fails to deserialize (#74499) +- Fix plugin applies_to scoping (#74425) +- Fix XCom query in not_previously_skipped_dep to use xcom_entity (#74377) +- Fix short-circuit in a mapped task group not skipping later tasks (#74283) +- UI : Fix duplicate "From" label on DAG backfill filters (#74189) +- Improve LocalExecutor bookkeeping: correctly add tasks to the ``running`` list (#74142) +- UI: Fix XCom list crash when a value request fails (#74131) +- Fix date range filter inputs committing on every keystroke (#74011) +- Fix short-circuit not skipping already expanded mapped tasks (#73960) +- Fix short-circuit inside a mapped task group not skipping downstream (#73959) +- UI: Fix external plugin nav links not navigating on click (#73913) +- Correctly shutdown async sessions on exit. (#73838) +- API: Translate domain ValueError in Task State Store route (#73753) +- Filter jobs API ``is_alive`` in SQL so pagination stays correct (#73684) +- Fix boolean value of start date used in url start_date_gte filter. (#73676) +- Fix square corner on fully filled dashboard History bars (#73543) +- Fix airflow plugins and dags pause printing prose with --output json (#73270) +- Fix 500 from POST ``/auth/token`` on a request body it cannot parse (#73258) +- Fix slow task-log scrolling by memoizing useLogGroups' visible-items index (#73252) +- Fix 500 from the audit logger on a request body it cannot parse (#73226) +- Stop reporting components as degraded after an instance restart (#73222) +- Fix dashboard stats cards navigating to a 404 page (#73178) +- Fix airflow db clean silently skipping three tables when scoped to Dags (#73173) +- Stop the scheduler creating Dag runs for paused partitioned-asset Dags (#73151) +- Fix Dags staying blocked by max_active_runs until the next parse (#73032) +- Fix airflow standalone announcing readiness before the API server is up (#73025) +- Fix airflow teams list --output json printing prose when no teams exist (#72945) +- Avoid a full asset table scan per request in simple auth manager (#72934) +- Fix Dag callbacks dropped when bundle versioning is disabled (#72930) +- Stop one malformed provider from breaking discovery for all providers (#72854) +- Fix backfill DagRuns being permanently starved from scheduling (#72730) +- Fix airflow db check reporting one fewer retry than it will make (#72708) +- Fix airflow dags list --columns help showing wrong default columns (#72607) +- Fix XCom slice endpoint for crossed bounds (#72584) +- Stop emitting the legacy first_task_scheduling_delay metric twice (#72512) +- Fix Dag metrics dropped when a tag contains invalid characters (#72364) +- Fix misleading error for malformed version in airflow db downgrade (#72331) +- Fix timedelta serde to accept int payloads (#72326) +- Fix plugin registration returning early on duplicate names in Task SDK (#72253) +- Keep the MeterProvider configured via OTEL_CONFIG_FILE (#71529) +- Fix Asset Event table titles showing a raw translation key (#71443) +- Fix executor validation error referencing non-existent [core] executors (#71336) +- Fix MySQL metadata database failing when only PyMySQL is installed (#71251) +- Fix OpenSearch remote logging crash if port is empty (#71170) +- Fix /ui/assets picking a stale "last event" under concurrent asset writes (#71047) +- Stop airflow config update from writing a backup during dry-run (#70979) +- Fix TypeError clearing a DAG run when a queued-at deadline interval is stored as JSON (#70370) +- Fix manual runs getting a zero-length data interval across DST (#70089) +- Use atomic upsert for asset run queue on MySQL to avoid deadlocks (#69977) +- Don't fail API server startup when a plugin uses an unknown team (#69976) +- Prevent negative trigger queue delay metrics (#69971) +- Fix asset event extra filter matching wrong events for dotted keys on SQLite (#69675) +- Fix @asset reserved keys with default value (#69642) +- Fix ``statsd_ipv6`` config not enabling IPv6 sockets for the default StatsD client (#69632) +- Make sure stale file handler doesn't crash the DagFileProcessorManager (#69324) +- UI: Fix triggered Dag run layout in asset event cards (#69310) +- Fix Dag detail page 500 for Dags without a fileloc #69035 (#69110) +- Fix mapped task group XCom collapsing to a bare value for a single expansion (#69075) +- Fix macOS SIGSEGV in triggerer and Dag processor via fork+exec (#69008) +- Fix branch not skipping mapped tasks with custom XCom backend (#68954) +- Fix duplicate heartbeat-timeout task callbacks (#68008) +- Drain result_queue in LocalExecutor to prevent process join deadlock (#67881) +- Fix CLI connection display reporting wrong is_extra_encrypted flag (#67561) +- Fix remote processor injection happening before dictConfig runs in configure_logging (#66633) +- Fix airflow db clean IntegrityError when a dag_version is referenced by a task_instance (#66350) +- Fix airflow db clean hang on MySQL when delete fails (#66296) +- Fix ``refresh_from_task`` not applied on retries (#65932) +- Fix asset event scheduling race condition and consistency (#62501) +- Fix ``DecreasingPriorityStrategy`` example by initializing ``try_number`` before weight evaluation (#62148) +- Fix connection resolution in CLI by setting server process context in decorators (#61036) + +Miscellaneous +^^^^^^^^^^^^^ + +- Update waiting tasks to the latest Dag version (#74592) +- Disable psycopg3 auto-prepare by default behind connection poolers (#74581) +- Make airflow standalone discover new Dag files within seconds (#74479) +- Use the configured API port in the default execution API URL (#74478) +- Dag run breadcrumb switcher (#74471) +- UI: Show important form inputs instead of hiding them in accordions (#74422) +- Speed up Migration 0136 on MySQL (#74409) +- Scope the mapped task group skip-decision query to its own Dag run (#74390) +- Chore UI deps major upgrades (#74369) +- Show loop iterations and outcomes throughout the UI (#74354) +- Show current task executions in the UI (#74352) +- Read current task executions by exact region and try (#74350) +- Clear selected loop work and regenerate only what was replaced (#74349) +- Resolve live producers by region and read their XCom by attempt (#74344) +- Parse native Go Dags and show each Dag's own source (#74341) +- UI: Apply default visibility to newly added table columns (#74320) +- UI: Group digits of counters in translated strings (#74296) +- Remember the Dag runs limit across tab switches and visits (#74289) +- Scope plugin views on any entity field, not a fixed criteria set (#74278) +- UI: Open provider connection fields by default and title them by connection type (#74273) +- Keep get_dag_details and get_pools database queries off the API server event loop (#74247) +- Guard the Dag Code tab's Monaco grammar exports against drift (#74246) +- Scope audit log rows to a Dag only from the request path or body (#74232) +- Register TypeScript, Java and Go grammars for the Dag Code tab (#74231) +- Discover executable bundles by footer, not by execute bit (#74227) +- Set end date and duration on tasks skipped by a Dag run timeout (#74128) +- Treat an empty Dag run config as no config in the UI (#74083) +- Let a Dag importer find the coordinator that parses its files (#74042) +- Validate a serialized Dag and fill its unset settings from the Airflow config (#74041) +- Keep the Dag trigger button one-click when a run has no config (#74039) +- Parse native TypeScript Dags with the Node coordinator (#74037) +- Parse native Java Dags and show their source (#74036) +- Parse native Lang-SDK Dags in the Dag processor with their runtime (#74035) +- Persist the match-anywhere search toggle in the URL (#74019) +- UI: Keep Dags list table rows on a single line (#74002) +- Pr/split storage tab (#73989) +- Surface Dag run conf in the header (#73987) +- Keep agent framework spans when worker tracing is off (#73903) +- Enforce execution_timeout from the task supervisor side (#73806) +- Keep the Dag asset schedule the same shape for every caller (#73805) +- Update supported Kubernetes versions (#73798) +- Always clear the session cookie on logout (#73788) +- Eager-load DagCode in the Dag source API (#73752) +- Speed up zip Dag discovery and keep member file names (#73727) +- UI: Group digits of counters according to the selected locale (#73713) +- Correct the meaning of _arg_bindings in the serialization schema (#73644) +- Sync the UI Dags list applied sort rule with URL query param (#73622) +- Link calendar cell to filter dagruns by the respective start_date and state. (#73611) +- Scope plugin scheduling classes to their team in multi-team mode (#73569) +- Warn when db clean skips only some rows of a batch (#73568) +- Widen revoked_token.jti to store external-issuer token identifiers (#73562) +- Own the BaseAsyncOperator event loop through asyncio.Runner (#73560) +- Use os.posix_spawn instead of fork+exec in the task-sdk supervisor (#73503) +- Skip ``on_kill()`` for triggers reassigned to another triggerer (#73454) +- Document favorite_dag's 409 and return a readable conflict message (#73411) +- Migrate ``GET /execution/variables/keys`` to an async DB session (#73407) +- Migrate execution API reads to async sessions (#73403) +- UI: Show every scheduler, triggerer, and Dag processor in health dashboard (#73355) +- UI: Show xcom before task state store in storage tabs (#73313) +- Delay reporting of up-for-retry state until task finalization completes (#73253) +- Refresh HITL review details on task clear (#73235) +- Scope plugin macros to their team in multi-team mode (#73224) +- Anchor top-level nav and needs-review links to root paths (#73202) +- Keep Grid scroll position when opening a task. (#73123) +- Identity-only DAG discovery and byte-importing (#73118) +- Move retry policy decision outside post execute log group block (#73023) +- Speed up the event logs API by loading only display names (#73021) +- Warn at provider discovery about an unresolvable connection type (#72904) +- Mark task-group aggregate bars on Gantt with a diagonal stripe (#72894) +- Hide unreadable assets in the asset expression served by next_run_assets (#72864) +- Scope UI next_run_assets endpoint to assets the caller may read (#72862) +- Keep date-only range ends inclusive (#72860) +- Require explicit limits for single-row lookups in core (#72856) +- Remove a misleading connection type warning and explain lookup failures (#72855) +- Keep callback triggers assigned to healthy triggerers (#72848) +- Remove ignored --output flag from airflow pools set and delete (#72833) +- Show whether a calendar day's run was a backfill (#72782) +- Replace AssertionError as ValueError in production code (#72763) +- Keep the task instance in dag callbacks when its Dag version is missing (#72721) +- Keep provider_config_fallback_defaults.cfg in sync with provider.yaml (#72549) +- Warn when connections/variables list output may be incomplete (#72484) +- Adjust warnings, import errors, and Dag source models for sdk/importers (#72474) +- Distinguish empty plugin folder from plugin load failures in logs (#72432) +- Preview JSON fields as inline badges in tables (#72353) +- More human readable duration strings (#72350) +- Avoid retrying XCom expand actions (#72305) +- Scope plugin operator extra links to their team in multi-team mode (#72231) +- Use a structured SecretCache key instead of a concatenated string (#72201) +- UI: Keep Grid run tooltips inside the viewport (#72161) +- UI: Stop list pages jumping while a filter loads (#72005) +- Include task_reschedule in task_instance dependent tables for db clean (#71990) +- UI: Visual overhaul of Dag details layout for easier consumption (#71957) +- Authorize team-scoped plugin API endpoints in multi-team mode (#71919) +- Remove the Go Edge Worker (#71874) +- UI: Make dialogs consistent and fix their dark mode background (#71806) +- UI: Unify list page filters and table header controls (#71731) +- Improve DAG authorization filtering performance (#71722) +- Extend user settings with additional configuration (#71699) +- Cut the per-file cost of persisting Dag parse results (#71621) +- UI: Consolidate table controls into consistent slots and improve visual presentation (#71554) +- Stop presenting multi-team tagged metrics as an exhaustive list (#71523) +- Show the teams of the signed-in user in multi-team mode (#71503) +- Backfills UI filters (#71467) +- Respect run on latest version when clearing a running Dag run (#71425) +- API: Return asset events for Dag Runs without a start date (#71379) +- Use sqlite3.sqlite_version_info instead of hand-parsing the version string (#71115) +- Validate provider metadata list entries instead of ignoring them (#71104) +- Reject serde-reserved keys in HITL params_input (#71054) +- Update grid view refresh (#71004) +- Improve assets list performance (#70997) +- Multi-Team: Add teams verify command to validate multi-team configuration (#70947) +- Describe default Airflow loggers (#70842) +- Rename dag serialization metrics. (#70838) +- Show user display names for triggered runs and HITL responses (#70836) +- UI: Preserve Dag tab when switching Dags (#70699) +- UI: Wire advanced-search toggle for Grid Triggering User filter (#70567) +- Rename airflowctl assets get-by-alias to get-alias (#70453) +- UI: Highlight selected Grid task square (#70451) +- Feature expand health endpoint reporting (#70416) +- Remove airflow-metadata.yaml sidecar support from NodeCoordinator (#70273) +- Show backfill Dag runs in the UI (#70159) +- UI: Pass Dag, DagRun, TaskInstance, and Asset objects to React app plugins (#70149) +- Rename Task and Asset store to Task and Asset state store (#70097) +- Skip timeout callback creation for Dags without on_failure_callback (#70065) +- Improve Dag run metrics (#70013) +- Sort Dags by latest run after (#69995) +- Updated sort+filters for Assets List (#69940) +- UI: Share one tooltip root across Dag card run-state badges (#69927) +- Progressively load interactive elements of Dag Card (#69806) +- Validate deferred trigger classpath resolves to a BaseTrigger subclass (#69792) +- Multi Team: Automatically create and assign team default pools (#69768) +- Pass dag_id to Dag bundle construction on task execution (#69697) +- Reduce DAG card tooltip controller overhead (#69681) +- Show recent task states on the Dags list page (#69619) +- Resolve NPM vulnerabilities in Simple auth manager (#69488) +- Display latest dagrun state per dag in search result. (#69414) +- Improve mobile responsiveness for dashboard asset cards (#69294) +- Thread version_data to callbacks (#69185) +- Mark task worker span as failed when the task fails (#69146) +- Handle DB Performance Issues by Adding a New Index for Trigger (#69038) +- Warm-shutdown supervisor on SIGTERM instead of killing the running task (#69034) +- Raise a warning instead of an error if extra teams are defined in the auth manager (#68935) +- UI: Show partition preview in backfill form for partitioned Dags (#68884) +- Display owner_display_name in Audit Log (#68833) +- Warn in UI when the same dag_id is registered from multiple files (#68791) +- Ignore stale executor success when TI is queued after defer (#68741) +- ``feature/issue-68575``: Add ``bundle_name`` to ``Dag`` (#68583) +- Optionally emit Dag tags as metric tags (#68568) +- Group and filter Dags by folder on the Dags page (#68544) +- TriggerRunner: Add batch trigger creation duration metric (#68521) +- Paginate partitioned Dag run modal requests (#68412) +- Gate raw Dag deserialization error detail behind api.expose_stacktrace and log it server-side (#68388) +- Avoid a supervisor round trip before poke for rescheduled sensors (#68012) +- TriggerRunnerSupervisor: Add trigger queue delay metric (#67927) +- Make kinit renewable lifetime configurable for Heimdal Kerberos support (#67804) +- Use async DB session for Execution API task-instance heartbeat (#67800) +- Type asset_expression in the REST API so the UI does not cast through unknown (#67725) +- Record TaskInstanceHistory when a task fails from a non-running state (#67372) +- Remove trigger event payload from INFO log in run_trigger() (#67244) +- Show per-Dag run state counts on the Dags list page (#67242) +- Improve doc_md rendering in Dag Documentation (#66809) + +Doc Only Changes +^^^^^^^^^^^^^^^^ + +- Add missing Taiwanese Mandarin translations (#74545) +- Add missing Polish UI translations (#74533) +- Add missing Taiwanese Mandarin translations for task states and Dag list settings (#74486) +- Fix Quick Start installing Airflow 3.1.1 instead of the documented version (#74474) +- Add missing UI translations for Greek(el) (#74460) +- Dedent task docstrings used as doc_md (#74436) +- Close Catalan gap (#74361) +- Fix mapped-task retry policy example in tasks docs (#74343) +- Close German Translation Gaps 2026-10-05 (#74264) +- Update French (fr) UI translations to 100% coverage (#74235) +- Add missing Taiwanese Mandarin UI translations (#74223) +- Close German Translation Gaps 2026-10-02 (#74088) +- Update docs and diagrams for the Airflow 3 Dag processor (#74073) +- Render the Language SDK Spec diagrams as Mermaid (#74065) +- Document HTTP statuses that route helpers raise (#74027) +- Use airflow.sdk imports in Airflow 3 upgrade guide example (#74015) +- i18n(ko): Add missing translations (Oct 1) (#74006) +- Document team-scoped plugins in multi-team mode (#73995) +- Close German Translation Gaps 2026-09-30 (#73980) +- Clarify Dag processor scoping and team config in Multi-Team docs (#73958) +- Fix typo in apache-airflow-providers-fab error message (#73956) +- Fix misleading timetable Variable example in best practices (#73945) +- Update the TypeScript SDK docs for Dags declared in TypeScript (#73875) +- i18n(ko): Align particles after Dag with the agreed pronunciation (#73799) +- i18n(ko): Add missing translations (Sep25) (#73757) +- Clarify max_db_retries doc wording to avoid off-by-one confusion (#73722) +- Fix typo in theme configuration screenshot filenames (#73632) +- Document that Go SDK registration closes at Serve (#73614) +- Update Go SDK docs for the airflow.Bundle authoring surface (#73528) +- i18n(zh-CN): align zh-CN Provider terminology and plural conventions (#73369) +- Fix wrong session type in state-store custom-backend doc example (#73361) +- Clarify the scope of db clean's ``--tables`` and DAG filter options (#73242) +- Add missing Traditional Chinese UI translations (#73180) +- Fix typos, grammar, and broken references across the docs (#73146) +- i18n(ko): Add missing translations (Sep14) (#73115) +- i18n(zh-CN): add missing translations (#73113) +- Fix syntax error and typos in FAQ doc (#73088) +- Fix broken code examples and stale references in airflow-core docs (#73077) +- Fix BaseXCom docstrings that say passing None removes a filter (#73066) +- Correct Airflow 3 systemd service and health guidance (#72872) +- Add missing zh-TW translations for common.json (#72766) +- Add a Language SDK spec to the Task SDK docs (#72765) +- Simplify the Quick Start for first-time local installs (#72754) +- Remove 值 from passwordToggle translations (#72684) +- UI: Complete Polish translations and unify slot/deferred wording (#72623) +- Add troubleshooting guidance for task state mismatches (#72492) +- Fix dead Docker Desktop networking links in the docker-compose guide (#72467) +- Improve Java SDK quick start setup docs (#72440) +- Update Catalan translations (main) (#72392) +- i18n(ko): add missing translations(Sep 1) (#72372) +- Fill in missing zh-TW translations for common.json (#72154) +- Fix stale TypeScript SDK docs on bundle metadata and packing setup (#72115) +- Complete the Taiwanese Mandarin UI translations (#72056) +- i18n(ko): add missing translations(Aug 25) (#72050) +- Update multi-team docs to match the teams CLI and name rules (#72045) +- Updated tutorial DAGs to use named parameters (#71980) +- Publish standalone Apache Airflow Mypy documentation (#71878) +- Document Go cross-language argument binding (#71871) +- Improve TypeScript SDK API reference navigation (#71833) +- Close spanish translation gap (#71796) +- i18n(Ko): add missing translations in assets.json (Aug 18) (#71760) +- Fix inverted docstring for config write hide_sensitive option (#71623) +- Fix the translation Gap for Taiwanese Mandarin (#71482) +- Update Deadline Reference docs to match the code (#71469) +- Document hook lineage collection limits (#71450) +- Document effect of clearing a task instance on task state store (#71356) +- Clarify that DAG.access_control is only read by the FAB auth manager (#71260) +- Document config-backed enum Dag Params (#71180) +- Fix broken translation guide links in the i18n README (#71179) +- Clarify which signal each duplicated otel_* config option applies to (#71158) +- Complete the Traditional Chinese UI translations (#71019) +- Clarify How to upgrade docs for PyPI installs (#70897) +- Add TypeScript SDK API reference docs with TypeDoc (#70812) +- i18n(Ko):Add missing translations in components.json (#70764) +- Align timetable docs with Airflow 3 data interval and catchup behaviour (#70658) +- Remove stale experimental note from Lineage docs (#70400) +- Update French (fr) UI translations to 100% coverage (#70386) +- Add missing zh-TW translations for team strings (#70321) +- Add TypeScript SDK guide to language SDKs docs (#70219) +- fix ruff check docs command in FAQ (#70212) +- Fill Taiwanese Mandarin translation gap (#70194) +- Align Dag Runs docs with Airflow 3 trigger timetable defaults (#70167) +- Document that Code view shows only Python source for stub tasks (#70155) +- Cleanup multi-team docs for team_name tagging (#70146) +- UI: Complete Hindi (hi) translation coverage (#70111) +- Enhance/standardize documentation for ``AssetOrTimeSchedule`` (#69831) +- Clarify the dags reserialize command scope (#69810) +- Document that connection secrets without conn_type remain supported (#69780) +- Update SQLAlchemy documentation link from 1.4 to 2.0 (#69775) +- Fill Taiwanese Mandarin translation gap (#69708) +- Mention min Java version in Java SDK README (#69691) +- Fill Taiwanese Mandarin translation gap (#69549) +- Regenerate REST API permission reference to fix static check (#69341) +- Fix the translation Gap for Taiwanese Mandarin (#69199) +- Document PostgreSQL fallback host connection strings (#69150) +- Add example DAG demonstrating Deadline Alerts (#66269) + Airflow 3.3.2 (2026-09-17) -------------------------- @@ -7880,3 +8652,26 @@ Doc only changes nvd lineChart + adelete + aget + akeys + aset + CN + Dedent + dialogs + exec'd + Heimdal + ko + Ko + memoizing + passwordToggle + poolers + Relatedly + serialised + spanish + theming + TW + useLogGroups + viewport + zh + 值 diff --git a/airflow-core/newsfragments/58543.feature.rst b/airflow-core/newsfragments/58543.feature.rst deleted file mode 100644 index da80079a161..00000000000 --- a/airflow-core/newsfragments/58543.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``AssetAndTimeSchedule`` timetable that schedules time-based runs gated on asset conditions. diff --git a/airflow-core/newsfragments/62501.bugfix.rst b/airflow-core/newsfragments/62501.bugfix.rst deleted file mode 100644 index bb2a30511d4..00000000000 --- a/airflow-core/newsfragments/62501.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a race condition that could cause asset-triggered Dags to be skipped when asset events were produced concurrently. The scheduler could miss a newly produced asset event because there was a visibility gap between when the record was flushed and when the producing task's transaction committed. The asset event is now committed ahead of the producing task's remaining bookkeeping to close that gap; in rare cases this can surface as a duplicate or orphaned asset event if that task fails im [...] diff --git a/airflow-core/newsfragments/63491.significant.rst b/airflow-core/newsfragments/63491.significant.rst deleted file mode 100644 index d81d2951d43..00000000000 --- a/airflow-core/newsfragments/63491.significant.rst +++ /dev/null @@ -1,60 +0,0 @@ -Unify executor workload queues under ``BaseExecutor.executor_queues`` - -Executor workload state is now stored on the unified ``BaseExecutor.executor_queues`` mapping -keyed by ``WorkloadType``, and scheduling is driven by ``trigger_workloads``. The previous -per-type attributes and entrypoints ``queued_tasks``, ``queued_callbacks``, ``supports_callbacks``, -``trigger_tasks``, and ``order_queued_tasks_by_priority`` are kept as backward-compatible shims -that emit ``RemovedInAirflow4Warning`` and will be removed in Airflow 4.0. - -The connection-test surface introduced in Airflow 3.3 (``supports_connection_test``, -``queued_connection_tests``, and ``trigger_connection_tests()``) is folded into the same -mechanism: connection tests are queued in ``executor_queues[WorkloadType.TEST_CONNECTION]`` -and dispatched by ``trigger_workloads`` alongside other workload types. A deprecated -``supports_connection_test`` compat attribute remains; ``queued_connection_tests`` and -``trigger_connection_tests()`` are removed without a shim. - -**Migration:** - -- Replace ``executor.queued_tasks`` with ``executor.executor_queues[WorkloadType.EXECUTE_TASK]``. -- Replace ``executor.queued_callbacks`` with ``executor.executor_queues[WorkloadType.EXECUTE_CALLBACK]``. -- Replace ``executor.queued_connection_tests`` with - ``executor.executor_queues[WorkloadType.TEST_CONNECTION]``. -- Replace ``supports_callbacks = True`` / ``supports_connection_test = True`` class declarations - by adding ``WorkloadType.EXECUTE_CALLBACK`` / ``WorkloadType.TEST_CONNECTION`` to the - ``supported_workload_types`` frozenset. -- Replace ``executor.trigger_tasks(open_slots)`` and ``executor.trigger_connection_tests()`` - with ``executor.trigger_workloads(open_slots)``. -- ``order_queued_tasks_by_priority()`` has no direct public replacement: workload ordering is - applied internally by ``trigger_workloads``. The deprecated shim now forwards to the private - ``_get_workloads_to_schedule(open_slots)`` helper, whose return shape differs from the old - method — it includes *all* queued workload types (not just tasks) and truncates the result - to the number of currently open slots. Subclasses that need a custom ordering should not - depend on the private helper; open an issue describing the use case instead. - -**Behavioural changes:** - -- Workload admission now uses a single per-heartbeat budget instead of independent budgets for - tasks and connection tests. Connection tests can no longer over-subscribe ``parallelism``, - and they are prioritized *ahead of* tasks (they are short-lived and user-interactive), so a - sustained task backlog no longer starves them. -- ``executor_queues`` is a ``collections.defaultdict`` and the per-``WorkloadType`` inner - queues auto-vivify on access; do not replace it with a plain ``dict``. - -Legacy ``supports_callbacks`` / ``supports_connection_test`` usage on out-of-tree executors is -still honored, with a deprecation warning in each case: - -- Class attributes: ``BaseExecutor.__init_subclass__`` folds ``= True`` / ``= False`` - declarations into ``supported_workload_types`` (adding or removing the type while preserving - everything else inherited from the parent class) and drops the plain bool so the compat - attribute keeps working on the subclass. -- Class-level reads (``SomeExecutor.supports_callbacks``) and instance reads still return a - ``bool`` derived from ``supported_workload_types``. -- Instance assignment (``self.supports_callbacks = True`` in ``__init__``) still works and toggles - the corresponding entry in that instance's ``supported_workload_types``. - -Subclasses that override the no-longer-invoked ``trigger_tasks``, ``trigger_connection_tests`` -or ``order_queued_tasks_by_priority`` methods also get a warning at class-definition time. - -Deprecation warnings for these compat entrypoints are emitted at most once per executor class to -avoid flooding scheduler heartbeat logs, and each is paired with a ``log.warning`` so it is -visible to out-of-tree executors regardless of Python warning-filter configuration. diff --git a/airflow-core/newsfragments/66350.bugfix.rst b/airflow-core/newsfragments/66350.bugfix.rst deleted file mode 100644 index b03dfd176e7..00000000000 --- a/airflow-core/newsfragments/66350.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Reduces the window where ``airflow db clean`` fails with an ``IntegrityError`` when a ``dag_version`` row was still referenced by a ``task_instance`` created between the archive ``INSERT`` and the ``DELETE``. diff --git a/airflow-core/newsfragments/66633.bugfix.rst b/airflow-core/newsfragments/66633.bugfix.rst deleted file mode 100644 index 5ea85be3152..00000000000 --- a/airflow-core/newsfragments/66633.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix remote task logs being silently dropped when ``dictConfig`` closes a remote logging handler during configuration. diff --git a/airflow-core/newsfragments/67372.bugfix.rst b/airflow-core/newsfragments/67372.bugfix.rst deleted file mode 100644 index 3cd5c2f6368..00000000000 --- a/airflow-core/newsfragments/67372.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix TaskInstanceHistory missing host/metadata when task is retried from a non-RUNNING state (e.g. killed externally or failed in queued/deferred status) diff --git a/airflow-core/newsfragments/67927.feature.rst b/airflow-core/newsfragments/67927.feature.rst deleted file mode 100644 index ca7500343a9..00000000000 --- a/airflow-core/newsfragments/67927.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added the ``triggerer.trigger_queue_delay`` metric, which measures the time a trigger workload spends queued before being processed by the trigger runner. diff --git a/airflow-core/newsfragments/68314.improvement.rst b/airflow-core/newsfragments/68314.improvement.rst deleted file mode 100644 index 02f93386790..00000000000 --- a/airflow-core/newsfragments/68314.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -The default PostgreSQL connection string now uses an explicit ``postgresql+psycopg2://`` SQLAlchemy dialect instead of the bare ``postgresql://`` scheme. SQLAlchemy 2.1 changes the implicit default from psycopg2 to psycopg (v3), so bare URLs silently change driver across upgrades. If your ``sql_alchemy_conn`` or Celery ``result_backend`` uses ``postgresql://``, switch to ``postgresql+psycopg2://`` (or ``postgresql+psycopg://`` if you intend to use psycopg v3). Airflow will continue to au [...] diff --git a/airflow-core/newsfragments/68496.significant.rst b/airflow-core/newsfragments/68496.significant.rst deleted file mode 100644 index ef0ee519977..00000000000 --- a/airflow-core/newsfragments/68496.significant.rst +++ /dev/null @@ -1,32 +0,0 @@ -Default async Postgres driver changed from asyncpg to psycopg3 - -When ``[database] sql_alchemy_conn_async`` is not set, Airflow derives the async metadata database URL from ``sql_alchemy_conn``. For PostgreSQL, the derived URL now uses psycopg3 (``postgresql+psycopg_async://``) instead of asyncpg (``postgresql+asyncpg://``) when psycopg3 is installed. If psycopg3 is not installed — for example with an older ``apache-airflow-providers-postgres`` release that ships ``asyncpg`` but not ``psycopg`` — the derived URL keeps using asyncpg, so upgrading ``apa [...] - -**Why:** Airflow recommends running PgBouncer in front of PostgreSQL in production. asyncpg uses named server-side prepared statements, which break under transaction-mode PgBouncer unless prepared-statement caching is explicitly disabled. psycopg3 is safe behind transaction-mode PgBouncer with no extra configuration, so the default async engine now works out of the box in recommended production deployments. - -The SQLite (``aiosqlite``) and MySQL (``aiomysql``) async URL derivations are unchanged, and an explicitly configured ``sql_alchemy_conn_async`` is never rewritten. - -**Packaging:** the ``apache-airflow-providers-postgres`` distribution now installs ``psycopg`` (psycopg3) by default, and ``asyncpg`` is no longer installed by default. Instead, it moved to the ``asyncpg`` optional extra. Note that Airflow versions older than 3.4.0 always derive an asyncpg URL (they have no psycopg3 fallback), so running the new provider release on an older Airflow version requires either the ``asyncpg`` extra or an explicitly configured ``sql_alchemy_conn_async``. - -**To keep using asyncpg**, install the extra and configure the async URL explicitly: - -.. code-block:: bash - - pip install 'apache-airflow-providers-postgres[asyncpg]' - -.. code-block:: ini - - [database] - sql_alchemy_conn_async = postgresql+asyncpg://<user>:<password>@<host>/<db> - -When running behind transaction-mode PgBouncer, also disable asyncpg's prepared-statement caching by pointing ``sql_alchemy_connect_args_async`` at a dict defined in ``airflow_local_settings.py``: - -.. code-block:: python - - # airflow_local_settings.py - connect_args_async = {"statement_cache_size": 0, "prepared_statement_cache_size": 0} - -.. code-block:: ini - - [database] - sql_alchemy_connect_args_async = airflow_local_settings.connect_args_async diff --git a/airflow-core/newsfragments/68517.significant.rst b/airflow-core/newsfragments/68517.significant.rst deleted file mode 100644 index f07598c3625..00000000000 --- a/airflow-core/newsfragments/68517.significant.rst +++ /dev/null @@ -1,14 +0,0 @@ -Asset-triggered Dags create one run per event by default - -Single-asset schedules and asset OR expressions now create one Dag run per event -instead of consuming all queued events in one run. This also applies to -``AssetOrTimeSchedule`` and ``PartitionedAssetTimetable``. - -To retain batching, set ``batch_asset_events=True`` on the timetable or enable -``[scheduler] batch_asset_events`` and reparse the affected Dags. Already serialized -timetables without this option retain their previous batching behavior until reparsed. - -Schedules requiring several events, including ``schedule=[a, b]``, asset AND -expressions, and partitioned timetables using ``RollupMapper``, continue to batch -by default. Explicitly setting ``batch_asset_events=False`` for these schedules -raises a timetable validation error. diff --git a/airflow-core/newsfragments/68521.feature.rst b/airflow-core/newsfragments/68521.feature.rst deleted file mode 100644 index 10c76c8b1c4..00000000000 --- a/airflow-core/newsfragments/68521.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added the ``triggerer.batch_trigger_creation_duration`` metric, which measures the total time spent creating pending triggers during a single trigger runner cycle. diff --git a/airflow-core/newsfragments/68548.feature.rst b/airflow-core/newsfragments/68548.feature.rst deleted file mode 100644 index b27224b817d..00000000000 --- a/airflow-core/newsfragments/68548.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add a Node.js task coordinator for running TypeScript task bundles through coordinator mode. diff --git a/airflow-core/newsfragments/68741.bugfix.rst b/airflow-core/newsfragments/68741.bugfix.rst deleted file mode 100644 index 897eee4180a..00000000000 --- a/airflow-core/newsfragments/68741.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Ignore stale executor success when a deferred task is rescheduled into QUEUED before the scheduler processes the stale SUCCESS from the worker. diff --git a/airflow-core/newsfragments/68760.significant.rst b/airflow-core/newsfragments/68760.significant.rst deleted file mode 100644 index 5b518af9993..00000000000 --- a/airflow-core/newsfragments/68760.significant.rst +++ /dev/null @@ -1,11 +0,0 @@ -Custom graph colors return via ``ui_color`` and ``ui_fgcolor`` - -The ``ui_color`` and ``ui_fgcolor`` attributes on operators and TaskGroups color the graph view -again -- the node fill from ``ui_color`` and the operator label from ``ui_fgcolor``, as they did in -Airflow 2. They were silently ignored since Airflow 3.0. - -The value can be a raw color (a hex code like ``#e8b7e4`` or a CSS name) or a Chakra theme token -- -a palette token such as ``blue.500`` or a semantic token such as ``brand.solid`` that adapts to -light and dark mode (including tokens added through custom UI theming); a token resolves through a -theme-controlled CSS variable. The node border keeps reflecting the task-instance run state; the -custom color is applied to the fill and label only. diff --git a/airflow-core/newsfragments/68791.improvement.rst b/airflow-core/newsfragments/68791.improvement.rst deleted file mode 100644 index 2c98be3c8ac..00000000000 --- a/airflow-core/newsfragments/68791.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -Warn in the UI when the same dag_id is registered from multiple files. diff --git a/airflow-core/newsfragments/68890.significant.rst b/airflow-core/newsfragments/68890.significant.rst deleted file mode 100644 index 0dc77788cc7..00000000000 --- a/airflow-core/newsfragments/68890.significant.rst +++ /dev/null @@ -1,6 +0,0 @@ -The ``airflow.utils.helpers.validate_key`` utility function now raises a ``ValueError`` instead of an ``AirflowException`` when an invalid key is provided (such as an invalid format or length limit violation). - -This change aligns the core function with the Task SDK's ``validate_key`` behavior. - -**Breaking Change for KubernetesPodOperator Users:** -Because ``validate_key`` is used internally by the ``KubernetesPodOperator`` to validate pod names, any DAGs that wrap ``KubernetesPodOperator`` execution in an ``except AirflowException`` block to catch invalid pod names will no longer catch this error. You must update your exception handling to catch ``ValueError`` instead. diff --git a/airflow-core/newsfragments/68954.bugfix.rst b/airflow-core/newsfragments/68954.bugfix.rst deleted file mode 100644 index eca1675dadf..00000000000 --- a/airflow-core/newsfragments/68954.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix branch operators not skipping mapped or cleared downstream tasks when a custom XCom backend is configured. diff --git a/airflow-core/newsfragments/69075.bugfix.rst b/airflow-core/newsfragments/69075.bugfix.rst deleted file mode 100644 index d992083c378..00000000000 --- a/airflow-core/newsfragments/69075.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix mapped task group return value handed to a downstream task being a bare value instead of a one-element list when the group expanded only once (and ``None`` instead of an empty list when every expansion returned ``None``). diff --git a/airflow-core/newsfragments/69469.significant.rst b/airflow-core/newsfragments/69469.significant.rst deleted file mode 100644 index 9ca750cb2b1..00000000000 --- a/airflow-core/newsfragments/69469.significant.rst +++ /dev/null @@ -1,26 +0,0 @@ -psycopg3 is now the default sync Postgres driver, with statement preparation disabled - -``psycopg`` (psycopg3) is now the default synchronous Postgres driver for the metadata database, mirroring the existing async default. A bare ``postgresql://``, or a legacy ``postgres://`` or ``postgres+psycopg2://``, ``sql_alchemy_conn`` is now rewritten to ``postgresql+psycopg://`` instead of ``postgresql+psycopg2://``, while an explicit ``postgresql+psycopg2://`` connection string is left untouched. Install the ``apache-airflow-providers-postgres[psycopg2]`` extra to keep using psycopg2. - -Airflow also sets ``prepare_threshold = None`` on both the sync and the async psycopg3 engine, which disables psycopg3's automatic server-side statement preparation. - -**Why:** psycopg3 prepares a statement server-side once it has been executed ``prepare_threshold`` times (5 by default). A pooler running in transaction mode routes consecutive transactions on one client connection to different server connections, so unless it tracks prepared statements itself, queries begin failing with ``InvalidSqlStatementName`` -- or ``DuplicatePreparedStatement`` where several clients generate the same statement name -- once the threshold is crossed. The Airflow Hel [...] - -No released version selected psycopg3 by itself, so this takes nothing away from an existing default installation. Deployments that already point ``sql_alchemy_conn`` or ``sql_alchemy_conn_async`` at ``postgresql+psycopg://`` or ``postgresql+psycopg_async://`` explicitly will stop preparing statements on upgrade. - -**To keep statement preparation** you need both halves; restoring ``prepare_threshold`` alone will reintroduce the failures above unless the pooler can handle it. - -First make the pooler safe for it. With PgBouncer that means 1.22 or newer, ``max_prepared_statements`` set above 0 (it defaults to 0 until 1.24, where it becomes 200), and ``libpq`` 17 or newer on the Airflow side -- see `the psycopg documentation <https://www.psycopg.org/psycopg3/docs/advanced/prepare.html#using-prepared-statements-with-pgbouncer>`_. Running without a pooler at all is also fine. - -Then put the setting back, by pointing ``sql_alchemy_connect_args`` at a dictionary defined in your ``airflow_local_settings.py``: - -.. code-block:: ini - - [database] - sql_alchemy_connect_args = airflow_local_settings.PSYCOPG3_CONNECT_ARGS - -.. code-block:: python - - PSYCOPG3_CONNECT_ARGS = {"prepare_threshold": 5} - -Anything set there is merged over the default and wins. The same applies to ``sql_alchemy_connect_args_async`` for the async engine. diff --git a/airflow-core/newsfragments/69675.bugfix.rst b/airflow-core/newsfragments/69675.bugfix.rst deleted file mode 100644 index 38ca8fd6068..00000000000 --- a/airflow-core/newsfragments/69675.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix asset event ``extra`` filtering silently matching the wrong events on SQLite when a filter key contains JSON-path metacharacters such as dots diff --git a/airflow-core/newsfragments/69768.feature.rst b/airflow-core/newsfragments/69768.feature.rst deleted file mode 100644 index fadc8880faa..00000000000 --- a/airflow-core/newsfragments/69768.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add automatic creation of team default pools in multi-team deployments and assign tasks without an explicitly configured pool to their team's default pool during Dag parsing. Existing multi-team deployments should run ``airflow teams sync`` after upgrading to provision default pools for existing teams. diff --git a/airflow-core/newsfragments/69790.feature.rst b/airflow-core/newsfragments/69790.feature.rst deleted file mode 100644 index 04e9bde8794..00000000000 --- a/airflow-core/newsfragments/69790.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Auth managers can scope read-only view authorization to a team via an optional ``team_name`` argument on ``is_authorized_view``, added to the auth manager interface in Airflow 3.4.0. It is supported by the Simple auth manager (shipped in Airflow) from 3.4.0, and by the Amazon, FAB, and Keycloak providers from the releases after 9.32.0, 3.7.2, and 0.8.1 respectively; older provider releases and auth managers that have not adopted the argument keep working but cannot restrict views per tea [...] diff --git a/airflow-core/newsfragments/69792.bugfix.rst b/airflow-core/newsfragments/69792.bugfix.rst deleted file mode 100644 index 5b9dfc15fc9..00000000000 --- a/airflow-core/newsfragments/69792.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Reject deferred-task trigger classpaths that do not resolve to a ``BaseTrigger`` subclass before the class is instantiated in the triggerer, so a deferred task cannot cause an arbitrary importable callable to be invoked in the triggerer process. diff --git a/airflow-core/newsfragments/70013.feature.rst b/airflow-core/newsfragments/70013.feature.rst deleted file mode 100644 index 428e22d49ea..00000000000 --- a/airflow-core/newsfragments/70013.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added a new ``scheduler.dagruns.queued`` metric alongside the existing ``scheduler.dagruns.running`` metric, so operators can track queued DagRun backlog (e.g. Dags stuck behind ``max_active_runs`` limits or pool exhaustion) as well as running load. Both metrics are emitted as a single untagged aggregate value across all Dags by default, matching the previous behaviour of ``scheduler.dagruns.running``. Set ``[scheduler] dagrun_metrics_per_dag_id`` to ``True`` to instead emit one gauge pe [...] diff --git a/airflow-core/newsfragments/70089.bugfix.rst b/airflow-core/newsfragments/70089.bugfix.rst deleted file mode 100644 index a8fa4b5e224..00000000000 --- a/airflow-core/newsfragments/70089.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix cron timetables that could schedule a Dag run for a period that has not elapsed yet on a DST transition day. diff --git a/airflow-core/newsfragments/70154.significant.rst b/airflow-core/newsfragments/70154.significant.rst deleted file mode 100644 index e97de862c45..00000000000 --- a/airflow-core/newsfragments/70154.significant.rst +++ /dev/null @@ -1 +0,0 @@ -The deprecated ``Dataset`` alias has been removed from the ``airflow`` module. Use ``Asset`` from ``airflow.sdk`` instead. diff --git a/airflow-core/newsfragments/70759.significant.rst b/airflow-core/newsfragments/70759.significant.rst deleted file mode 100644 index 3b3c864d53b..00000000000 --- a/airflow-core/newsfragments/70759.significant.rst +++ /dev/null @@ -1,24 +0,0 @@ -Audit log rows not tied to a Dag now require the ``AUDIT_LOGS_ALL`` view - -Rows in the audit log whose ``dag_id`` is ``NULL`` record operations that are not tied to a -Dag, such as Connection, Variable and Pool changes. They were returned to any caller that -could read event logs at all, because there is no per-Dag key to authorize them on and both -read paths fell back to a Dag-level audit log check. - -They are now gated on a dedicated ``AccessView.AUDIT_LOGS_ALL``, in the same way -``AccessView.IMPORT_ERRORS_ALL`` gates import errors for files with no registered Dag. Rows -bound to a Dag keep their existing per-Dag check. - -**Behaviour changes:** - -- ``GET /eventLogs`` no longer returns rows with a ``NULL`` ``dag_id`` to callers without the - new view, and excludes them from ``total_entries`` and pagination. - ``GET /eventLogs/{event_log_id}`` returns ``403`` for such a row. An id matching no row - still returns ``404``. -- With the simple auth manager the view is granted to the ``ADMIN`` role only. With the FAB - auth manager it maps to a new ``All Audit Logs`` resource, which ships in the ``Admin`` - role; custom roles that need to read these rows must be granted - ``All Audit Logs.can_read`` explicitly. -- An auth manager that cannot map a requested ``AccessView`` now denies that view and emits - a ``UserWarning`` instead of raising ``KeyError``. This affects auth managers older than - the core they run against, which previously failed the request with a server error. diff --git a/airflow-core/newsfragments/70838.feature.rst b/airflow-core/newsfragments/70838.feature.rst deleted file mode 100644 index e54e473fc45..00000000000 --- a/airflow-core/newsfragments/70838.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added the ``dag.serialization.version_created`` and ``dag.serialization.version_updated`` metrics, which count Dag serializations in each of the two situations where serialization happens: when a new Dag version is created, and when the latest Dag version is updated in place. diff --git a/airflow-core/newsfragments/70886.significant.rst b/airflow-core/newsfragments/70886.significant.rst deleted file mode 100644 index d772b43d169..00000000000 --- a/airflow-core/newsfragments/70886.significant.rst +++ /dev/null @@ -1,19 +0,0 @@ -Team names must now be lower case, and cannot contain two consecutive underscores - -``airflow teams create`` and ``airflow teams sync`` now accept only names matching -``(?!.*__)[a-z0-9_-]{3,50}`` -- lower case letters, digits, hyphens and single -underscores. Upper case letters and ``__`` were previously accepted. - -A team name is embedded in the ``AIRFLOW_CONN__<TEAM>___<ID>`` environment variable -namespace that holds team scoped secrets, and the backend upper-cases the name when it -builds that variable. ``data_eng`` and ``Data_Eng`` therefore resolved a single -namespace between them, and a name containing ``___`` could not be told apart from the -separator. - -``airflow db migrate`` lower-cases every stored team name, moving that team's Dag -bundles, Connections, Variables, Pools and Triggers with it. Two stored names that -differ only in case would collapse onto one row and silently merge two teams, so -migration refuses to start while any such pair exists -- rename all but one first. Names -that stay invalid for another reason, such as containing ``__``, are migrated as they -are; they keep working, but ``airflow teams sync`` exits non-zero until they are -renamed. diff --git a/airflow-core/newsfragments/70947.feature.rst b/airflow-core/newsfragments/70947.feature.rst deleted file mode 100644 index 1d0f8ab6aff..00000000000 --- a/airflow-core/newsfragments/70947.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add an ``airflow teams verify`` CLI command for validating multi-team configuration. The command checks that each team has its system-managed default pool, that DAG bundles reference existing teams, and reports any configuration inconsistencies. diff --git a/airflow-core/newsfragments/70972.significant.rst b/airflow-core/newsfragments/70972.significant.rst deleted file mode 100644 index bae78066f12..00000000000 --- a/airflow-core/newsfragments/70972.significant.rst +++ /dev/null @@ -1,13 +0,0 @@ -Changes to how pending asset events trigger Dag runs - -Deleting asset event records with ``airflow db clean`` now also removes any -asset events that are still pending for a downstream Dag. This mainly affects -Dags waiting on a multi-asset condition, where a pending event can be purged -before the condition is met. Deleting an asset event now consistently means it -will not trigger a run; previously such a pending trigger could still fire after -the event had been purged. - -Relatedly, an asset event that was queued for a Dag while it was scheduled on -that asset is still used to trigger the run, and appears among the run's -triggering events, even if the asset is later removed from the Dag's schedule. -Previously, they were silently dropped. diff --git a/airflow-core/newsfragments/71192.significant.rst b/airflow-core/newsfragments/71192.significant.rst deleted file mode 100644 index 6d3119377d6..00000000000 --- a/airflow-core/newsfragments/71192.significant.rst +++ /dev/null @@ -1,12 +0,0 @@ -Callbacks now redeem a single-use token before they run - -A worker now redeems a callback's single-use token with the API server -(``PATCH /execution/callbacks/{callback_id}/run``) before importing and running the callback. -Redeeming the token moves the callback from queued to running and swaps it for a short-lived -execution-scoped token. Before this change a callback ran without the worker making any -authenticated call, so the token minted for it was never checked. - -Because the token is single-use, a redelivered or replayed message that reaches a callback that is -already running or finished is refused rather than run again. A worker on 3.4 needs an API server -that serves this endpoint; a worker talking to an older API server negotiates the API version and -behaves as though the endpoint is not there. diff --git a/airflow-core/newsfragments/71251.bugfix.rst b/airflow-core/newsfragments/71251.bugfix.rst deleted file mode 100644 index ef127bdac38..00000000000 --- a/airflow-core/newsfragments/71251.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``import airflow`` failing with a ``RuntimeError`` demanding ``mysqlclient`` when a MySQL connection string was configured and only ``PyMySQL`` was installed. Each driver is now configured independently, and the error is raised only when neither is available. diff --git a/airflow-core/newsfragments/71729.improvement.rst b/airflow-core/newsfragments/71729.improvement.rst deleted file mode 100644 index d85f81ee6fe..00000000000 --- a/airflow-core/newsfragments/71729.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``--limit`` option to ``airflow dags list-runs`` to cap output to the N most recent Dag runs after filters and sorting are applied, mirroring ``airflow dags list-jobs --limit``. diff --git a/airflow-core/newsfragments/71957.improvement.rst b/airflow-core/newsfragments/71957.improvement.rst deleted file mode 100644 index a6607bc7f90..00000000000 --- a/airflow-core/newsfragments/71957.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -The Dag details breadcrumb now doubles as a Dag switcher: the first level names the current Dag and a chevron beside it opens the Dag search in place, replacing the separate search button that sat next to the breadcrumb. The ``mod+k`` shortcut opens this switcher. The pause toggle has moved out of the breadcrumb to sit with the other Dag actions in the page header, where it is available on every Dag page rather than only on deeper ones. diff --git a/airflow-core/newsfragments/71968.bugfix.rst b/airflow-core/newsfragments/71968.bugfix.rst deleted file mode 100644 index a312ab29091..00000000000 --- a/airflow-core/newsfragments/71968.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -``Variable.get``, ``Variable.get_variable_from_secrets`` and ``Variable.setdefault`` now accept an optional keyword-only ``session`` that is forwarded to the metastore secrets backend. A lookup made while holding an open session (most notably inside the scheduler's ``prohibit_commit`` guard) now reuses the caller's transaction instead of opening a scoped session and committing it. ``Variable.update`` now forwards its session to its own existence check, which had the same problem. diff --git a/airflow-core/newsfragments/71990.bugfix.rst b/airflow-core/newsfragments/71990.bugfix.rst deleted file mode 100644 index 819b6ab5953..00000000000 --- a/airflow-core/newsfragments/71990.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``airflow db clean`` to include ``task_reschedule`` in ``task_instance`` dependent tables so task reschedules are cleaned and archived prior to task instances. diff --git a/airflow-core/newsfragments/72036.feature.rst b/airflow-core/newsfragments/72036.feature.rst deleted file mode 100644 index c28d6e32467..00000000000 --- a/airflow-core/newsfragments/72036.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add an ``airflow teams inspect`` CLI command for displaying resources associated with a team, including Dag bundles, pools, connections, and variables. diff --git a/airflow-core/newsfragments/72100.significant.rst b/airflow-core/newsfragments/72100.significant.rst deleted file mode 100644 index e0c94bce297..00000000000 --- a/airflow-core/newsfragments/72100.significant.rst +++ /dev/null @@ -1,59 +0,0 @@ -Clearing a task now discards its task state store entries by default - -Clearing a task instance discards its ``task_state_store`` entries, so the next attempt starts from -the beginning instead of resuming from a checkpoint or reconnecting to an external job recorded by -the attempt that was cleared. - -Retries are unaffected. They keep task state exactly as before, which is what crash recovery relies -on. Only a deliberate clear discards. - -This only applies to clearing individual task instances (the task-instance clear endpoint / dialog, -and ``airflowctl dags clear``, which clears every task instance in the matched Dag run(s) through -the same endpoint). Clearing an entire Dag run through the "Clear Run" dialog/API, and marking a -task as failed or success (which clears downstream tasks as a side effect), still keep task state -unconditionally today; extending discard-by-default to those paths is tracked in -`#72929 <https://github.com/apache/airflow/issues/72929>`_. - -**Why** - -Clearing means "run this again". A checkpoint records how far a task got, not what it got there -with, so resuming after the code or the upstream data changed left work done before the fix in place -and silently mixed it with the corrected work. Clearing a task whose external job had already -succeeded was worse: the operator read the stored result back and returned in seconds having run -nothing. - -**Keeping the old behaviour** - -Pass ``keep_task_state=True`` to the clear task instances endpoint, or tick "keep task state" in the -clear dialog. Use it when nothing about the inputs or the code changed and the task should carry on -where it stopped, or when an external job is still running and you want the next attempt to -reconnect rather than submit a duplicate. To make "keep task state" the default so you don't have to -tick it on every clear, turn it on under Settings > Clearing > "Keep task state on clear"; that -default is per-browser and does not affect anyone else on the same deployment. - -Operators with durable execution are worth particular attention. Clearing a *failed* task never runs -``on_kill``, so an external job that outlived its worker is still running, and discarding the stored -id means submitting a second one. The same applies to operators configured to leave their job alive -on kill, such as ``GlueJobOperator``, which defaults ``stop_job_run_on_kill`` to ``False``. - -This also widens the permission surface of clearing: a task-instance clear (gated by the -task-instance edit permission) now deletes ``task_state_store`` rows for that task instance, the same -rows the dedicated task-state-store endpoint gates behind the delete permission. - -On the CLI, ``airflowctl tasks clear`` discards task state the same way and has a -``--keep-task-state`` flag to opt back in. ``airflowctl dags clear`` discards task state too, since -it clears every task instance in the matched Dag run(s) through the same endpoint, but it has no -``--keep-task-state`` equivalent yet. ``airflow dags clear`` and ``airflow tasks clear`` -(airflow-core; only ``tasks clear`` is deprecated, in favor of ``airflowctl tasks clear``) are -unaffected: they call ``clear_task_instances()`` directly and never touch task state. - -* Types of change - - * [ ] Dag changes - * [ ] Config changes - * [x] API changes - * [x] CLI changes - * [x] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/72164.significant.rst b/airflow-core/newsfragments/72164.significant.rst deleted file mode 100644 index 29532d28699..00000000000 --- a/airflow-core/newsfragments/72164.significant.rst +++ /dev/null @@ -1,23 +0,0 @@ -``[core] execute_tasks_new_python_interpreter`` now applies to Airflow 3 task processes - -On Airflow 3 the option had no effect on task execution (only the Edge worker read it). When set to -``True``, the task supervisor now ``exec``\ s a fresh interpreter right after forking the task process, -which prevents the fork from inheriting a lock held by a supervisor thread (a permanent hang at the -task's first TLS call). Deployments that kept the option ``True`` from Airflow 2 get this behaviour, -and its per-task interpreter start-up cost, on upgrade without further action; set it to ``False`` to -keep bare fork. The task process reads the global value, so a team-scoped Edge setting alone does not -turn it on. Edge workers with the option ``True`` already start a fresh interpreter for the supervisor -and will now start a second one for the task. The Dag processor, the triggerer and task -callbacks (which the callback supervisor runs from a closure that cannot be named for an exec'd -child) are not affected and keep bare fork. - -* Types of change - - * [ ] Dag changes - * [x] Config changes - * [ ] API changes - * [ ] CLI changes - * [x] Behaviour changes - * [ ] Plugin changes - * [ ] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/72407.significant.rst b/airflow-core/newsfragments/72407.significant.rst deleted file mode 100644 index fb0e84bb568..00000000000 --- a/airflow-core/newsfragments/72407.significant.rst +++ /dev/null @@ -1,23 +0,0 @@ -Gracefully pause Dags by draining active runs (#72407, #73225, #73055, #73763) - -Airflow now supports a ``draining`` scheduling state for Dags. Draining stops -the scheduler from creating new scheduled or asset-triggered Dag runs while -allowing already queued and running Dag runs to continue. Explicitly triggered -runs remain allowed. - -After outstanding Dag runs finish, the Dag automatically transitions to -``paused``. Users can cancel draining to return the Dag to ``active``. - -Manual runs, backfills and asset materializations on a paused Dag can drain -the Dag instead of unpausing it: choose **Drain** in the UI, or set -``drain_dag`` in the REST API request. Draining lets unfinished runs of -the Dag start or resume, except those held by paused backfills, creates no -scheduled runs, and pauses the Dag again once all unfinished runs finish. -Paused backfills remain paused and must be resumed for their runs to finish -and draining to complete. - -The UI, REST API, and ``airflowctl`` expose the ``active``, ``draining``, and -``paused`` scheduling states, and the Dags list can pause, drain, or unpause -several selected Dags at once. Existing ``is_paused`` API usage remains -supported; use ``scheduling_state`` when the draining state must be selected or -reported explicitly. diff --git a/airflow-core/newsfragments/72494.feature.rst b/airflow-core/newsfragments/72494.feature.rst deleted file mode 100644 index 4406eb0e89a..00000000000 --- a/airflow-core/newsfragments/72494.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``--dry-run`` to ``airflow teams sync`` so deployments can preview missing teams and default team pools without writing to the metadata database. diff --git a/airflow-core/newsfragments/72682.feature.rst b/airflow-core/newsfragments/72682.feature.rst deleted file mode 100644 index b005272f4f8..00000000000 --- a/airflow-core/newsfragments/72682.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Auth managers can now restrict which assets a user may see: ``BaseAuthManager`` gains ``get_authorized_assets`` and ``filter_authorized_assets``, ``AssetDetails`` now carries the asset's ``name`` and ``uri`` so an implementation can authorize on a URI prefix rather than an opaque id, and the asset list and asset events endpoints scope both their rows and their ``total_entries`` to the assets the caller may read. The default implementation calls ``is_authorized_asset`` once per asset, so [...] diff --git a/airflow-core/newsfragments/72896.significant.rst b/airflow-core/newsfragments/72896.significant.rst deleted file mode 100644 index 44230aa6850..00000000000 --- a/airflow-core/newsfragments/72896.significant.rst +++ /dev/null @@ -1,16 +0,0 @@ -Reparsing a file with no registered Dag now requires the ``REPARSE_ALL`` view - -A file that failed to import before defining any Dag has no per-Dag key to authorize a reparse -against, so ``PUT /parseDagFile/{file_token}`` previously returned ``404`` for it. Reparsing such a -file is now gated on a dedicated ``AccessView.REPARSE_ALL`` -- a write action of its own, distinct -from the permission to view import errors -- and the Dag import errors modal gains a reparse action -for these files. - -**Behaviour changes:** - -- ``PUT /parseDagFile/{file_token}`` for a file with no registered Dag authorizes against - ``REPARSE_ALL`` and returns ``403`` when the caller lacks it, instead of ``404``. A file that has a - registered Dag keeps its existing per-Dag ``can_edit`` check. -- With the simple auth manager the view is granted to the ``ADMIN`` role only. With the FAB auth - manager it maps to a new ``All Reparses`` resource, which ships in the ``Admin`` role; custom roles - that need to reparse such files must be granted ``All Reparses.can_read`` explicitly. diff --git a/airflow-core/newsfragments/73054.significant.rst b/airflow-core/newsfragments/73054.significant.rst deleted file mode 100644 index 44b4a0f3467..00000000000 --- a/airflow-core/newsfragments/73054.significant.rst +++ /dev/null @@ -1,13 +0,0 @@ -Removed the ``--file-io`` option from the ``airflow info`` command - -``--file-io`` uploaded the report to file.io and printed a shareable link. file.io no longer -accepts anonymous uploads, so the option could not succeed; it also ended in an unhandled -traceback rather than reporting the failure. - -Redirect the output instead:: - - airflow info --anonymize > airflow-info.txt - -Note that ``--file-io`` applied ``--anonymize`` implicitly. Pass ``--anonymize`` explicitly when -sharing a report: plain ``airflow info`` prints connection strings, including passwords, in -cleartext. diff --git a/airflow-core/newsfragments/73244.significant.rst b/airflow-core/newsfragments/73244.significant.rst deleted file mode 100644 index 0c3c6e375c4..00000000000 --- a/airflow-core/newsfragments/73244.significant.rst +++ /dev/null @@ -1,22 +0,0 @@ -Task heartbeats are no longer retried by ``[workers] execution_api_retries`` - -Heartbeats had two overlapping retry mechanisms: the Task SDK API client retried -every request, including heartbeats, and the supervisor separately counted -consecutive heartbeat failures against ``[workers] max_failed_heartbeats``. The -client retries also had the unwanted side-effect of blocking the supervisor's -monitor loop while it backed off, so during an API server outage the supervisor -would be delayed forwarding task logs and/or noticing that the task subprocess -had exited. - -Heartbeat retries are now governed solely by ``max_failed_heartbeats``, whose -default has been adjusted from ``3`` to ``30`` to keep roughly the same -tolerance for an unreachable API server as the two mechanisms combined gave -before. - -If you have set ``[workers] max_failed_heartbeats`` explicitly, you may wish -reconsider value you have chosen. It is now the whole retry budget: with the -default ``[workers] min_heartbeat_interval`` of 5 seconds, the worker tolerates -roughly ``5 * max_failed_heartbeats`` seconds of API unavailability before -terminating a running task. You should likely keep the resulting value below any -configured ``[scheduler] task_instance_heartbeat_timeout`` (default 300 -seconds). diff --git a/airflow-core/newsfragments/73294.significant.rst b/airflow-core/newsfragments/73294.significant.rst deleted file mode 100644 index 33995056919..00000000000 --- a/airflow-core/newsfragments/73294.significant.rst +++ /dev/null @@ -1,14 +0,0 @@ -Deadline alert callbacks are validated at Dag parse time, and numeric intervals are deprecated - -``DeadlineAlert`` now refuses a ``callback`` that is not exactly ``AsyncCallback`` or -``SyncCallback``, so a subclass fails when the Dag is parsed rather than when the scheduler -reads it back. The scheduler decodes stored callbacks by exact class name so no class -named by a Dag author is imported or instantiated there, which means a subclass could be -written and then never read. - -Passing a number as the ``interval`` is deprecated and now emits ``RemovedInAirflow4Warning``. -It is still accepted and taken as a count of seconds, but the supported types are ``timedelta`` -and ``VariableInterval``. A ``timedelta`` subclass such as ``pendulum.duration(...)`` is -accepted and normalized to a plain ``timedelta``, where previously it passed validation and -then failed during serialization. ``interval=True`` is refused, because ``bool`` is an ``int`` -subclass and would otherwise be taken as one second. diff --git a/airflow-core/newsfragments/73328.significant.rst b/airflow-core/newsfragments/73328.significant.rst deleted file mode 100644 index 78349399960..00000000000 --- a/airflow-core/newsfragments/73328.significant.rst +++ /dev/null @@ -1,6 +0,0 @@ -The ``POST /assets/{asset_id}/materialize`` endpoint now requires a JSON request body. - -Previously a request with no body was accepted and the asset was materialized with default -values. The endpoint now requires an explicit JSON body, consistent with the other mutating -endpoints: a request without a body is rejected with ``422``, and an empty HTML form is not a -valid input anymore. All body fields remain optional, so an empty object (``{}``) is a valid body. diff --git a/airflow-core/newsfragments/73554.significant.rst b/airflow-core/newsfragments/73554.significant.rst deleted file mode 100644 index afa1047a804..00000000000 --- a/airflow-core/newsfragments/73554.significant.rst +++ /dev/null @@ -1,24 +0,0 @@ -TaskInstance try numbers now increase before the next try starts - -.. note:: - If you have any external systems that look at task logs or TI state for an - up-for-retry TI, you will need to be aware of this change and update your - code. - - For example, if you made a request to ``GET - /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}`` expecting - to get info about the failed try, you will now need to look at ``GET - /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/tries/{try_number - 1}`` - -When a task is up_for_retry, try_number now identifies the upcoming try. To -retrieve the try that failed, request ``/tries/{try_number - 1}``. The UI shows -the pending try and provides a link to the previous try's logs. - -Airflow now allocates a task instance's UUID and try number together immutably -so they consistently identify the same try. - -Previously when a task entered the retry cooldown period, it would be given a -new UUID, but keep on try number N and have the state of UP_FOR_RETRY until that -period was up (at which point that try would be marked FAILED and the try number -incremented). Instead, the failed try is immediately marked with state of -FAILED, and a new try created in state UP_FOR_RETRY. diff --git a/airflow-core/newsfragments/73746.significant.rst b/airflow-core/newsfragments/73746.significant.rst deleted file mode 100644 index 6d976dfc2b5..00000000000 --- a/airflow-core/newsfragments/73746.significant.rst +++ /dev/null @@ -1,22 +0,0 @@ -Deprecate cyclic TaskGroup dependencies - -A Dag whose TaskGroups depend on each other in a cycle, when each TaskGroup is treated as a single unit, -now issues a ``TaskGroupCycleDeprecationWarning`` at parse time and shows a Dag warning in the UI that -names the TaskGroups and tasks involved. These Dags still parse and run, because their task dependencies -are acyclic, but Airflow 3.5 is planned to reject them at parse time. - -A dependency into or out of any task in a TaskGroup counts as a dependency of the whole group, so a path -that leaves a TaskGroup and comes back into it is a cycle. For example, ``a >> bridge >> b``, with ``a`` -and ``b`` in the same TaskGroup and ``bridge`` outside it, makes the group depend on ``bridge`` and -``bridge`` depend on the group, even if ``a >> b`` is also set. - -**Migration:** - -- Move tasks between TaskGroups, or out of them, so that each group depends on the others in one direction - only. In the example above, move ``bridge`` into the group, or move ``b`` out of it. -- To catch these Dags in CI, run your Dag tests with - ``-W error::airflow.sdk.exceptions.TaskGroupCycleDeprecationWarning``. The check runs when a Dag is - added to a ``DagBag``, so only tests that load your Dags into a ``DagBag`` and assert there are no import - errors catch them; a test that only imports a Dag file does not. - -See "Cyclic TaskGroup dependencies" in the Dags documentation. diff --git a/airflow-core/newsfragments/73806.improvement.rst b/airflow-core/newsfragments/73806.improvement.rst deleted file mode 100644 index 0c50d09b67d..00000000000 --- a/airflow-core/newsfragments/73806.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -``execution_timeout`` is now also enforced by the task supervisor. A task process that does not stop on its own within ``[core] killed_task_cleanup_time`` seconds after the timeout elapses is sent SIGTERM and then SIGKILL, so tasks stuck in native code or with a broken signal handler no longer run forever. diff --git a/airflow-core/newsfragments/73970.significant.rst b/airflow-core/newsfragments/73970.significant.rst deleted file mode 100644 index 886d1d6ca0a..00000000000 --- a/airflow-core/newsfragments/73970.significant.rst +++ /dev/null @@ -1,5 +0,0 @@ -Language SDK coordinators load task handlers from a Dag bundle - -The experimental ``jars_root`` (Java) and ``executables_root`` (Go) coordinator kwargs are removed. -Put the artifacts in a Dag bundle registered in ``[dag_processor] dag_bundle_config_list`` and set ``task_handler_bundle_name`` in the coordinator's ``kwargs``, or leave it unset to use the task's own Dag bundle. -A config that still sets a removed kwarg fails with ``Cannot instantiate coordinator '<key>'``. diff --git a/airflow-core/newsfragments/74151.significant.rst b/airflow-core/newsfragments/74151.significant.rst deleted file mode 100644 index dbfa8d889d0..00000000000 --- a/airflow-core/newsfragments/74151.significant.rst +++ /dev/null @@ -1,17 +0,0 @@ -Support for Python 3.10 has been removed - -Airflow now requires Python 3.11 or newer. Python 3.10 reaches its end of life in October 2026, -and Airflow drops support for a Python version in ``main`` as soon as it reaches end of life. -The ``apache-airflow`` distribution, the Task SDK, ``airflowctl`` and all providers released -from ``main`` declare ``requires-python = ">=3.11"``. - -* Types of change - - * [ ] Dag changes - * [ ] Config changes - * [ ] API changes - * [ ] CLI changes - * [ ] Behaviour changes - * [ ] Plugin changes - * [x] Dependency changes - * [ ] Code interface changes diff --git a/airflow-core/newsfragments/74278.feature.rst b/airflow-core/newsfragments/74278.feature.rst deleted file mode 100644 index b6fba929773..00000000000 --- a/airflow-core/newsfragments/74278.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Plugin external views and React apps can be scoped with an optional ``applies_to`` block, a map of dotted field path to the values that path may take, such as ``{"state": ["failed"], "dag.tags.name": ["ml"]}``. This replaces the five fixed criteria added earlier in this development cycle and never released (``dag_tags``, ``dag_ids``, ``task_ids``, ``operators``, ``operator_names``). A path naming a field no record has is treated as a misconfiguration rather than a filter that never match [...] diff --git a/airflow-core/newsfragments/74499.bugfix.rst b/airflow-core/newsfragments/74499.bugfix.rst deleted file mode 100644 index c32f1614959..00000000000 --- a/airflow-core/newsfragments/74499.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the scheduler crashing, and crashing again on every restart, when a queued Dag run's Dag cannot be deserialized, for example because a custom timetable reads a missing Variable. The run is now logged and skipped until its Dag loads. diff --git a/airflow-core/newsfragments/task-loops.feature.rst b/airflow-core/newsfragments/task-loops.feature.rst deleted file mode 100644 index 385d11d75a3..00000000000 --- a/airflow-core/newsfragments/task-loops.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Repeat decorated task groups with runtime loop conditions and selective clearing using ``.loop()``.
