Skip to content

Release history

Apache Airflow releases

Platform to programmatically author, schedule, and monitor workflows.

All releases

13 shown

No immediate action
airflow-ctl/0.1.5 New feature

dags exec cmd + bulk delete + AIP-103

Review required
3.2.2 Breaking risk
Auth RCE / SSRF

SMTP TLS validation + UI prefix search + triggerer watchdog

helm-chart/1.21.0 Breaking risk
⚠ Upgrade required
  • Update Helm chart values: migrate any existing workers.* settings to the new workers.celery.* or workers.kubernetes.* locations before the deprecated keys are removed.
  • Be aware of the default Airflow image change to version 3.2.0; review any custom image overrides.
Breaking changes
  • Deprecation of all top-level workers.* configuration keys (e.g., workers.safeToEvict, workers.hostAliases, etc.) in favor of workers.celery.* and workers.kubernetes.*; these will be removed in a future version.
  • Default Airflow image updated from 3.1.8 to 3.2.0.
Notable features
  • Added ttlSecondsAfterFinished field for the database cleanup job.
  • Enabled tpl rendering in ServiceAccount annotations, metadataConnection, and config ConfigMap names.
Full changelog

Significant Changes

Workers config options have been moved under workers.celery.* and workers.kubernetes.*

Please update your configuration accordingly:

  • workers.safeToEvict is now deprecated in favor of workers.celery.safeToEvict/workers.kubernetes.safeToEvict (#61915).
  • workers.hostAliases is now deprecated in favor of workers.celery.hostAliases/workers.kubernetes.hostAliases (#61960).
  • workers.priorityClassName is now deprecated in favor of workers.celery.priorityClassName/workers.kubernetes.priorityClassName (#61961).
  • workers.runtimeClassName is now deprecated in favor of workers.celery.runtimeClassName/workers.kubernetes.runtimeClassName (#61962).
  • workers.schedulerName is now deprecated in favor of workers.celery.schedulerName/workers.kubernetes.schedulerName (#62030).
  • workers.serviceAccount is now deprecated in favor of workers.celery.serviceAccount/workers.kubernetes.serviceAccount (#64730).
  • workers.extraContainers is now deprecated in favor of workers.celery.extraContainers/workers.kubernetes.extraContainers (#64739).
  • workers.extraInitContainers is now deprecated in favor of workers.celery.extraInitContainers/workers.kubernetes.extraInitContainers (#64741).
  • workers.extraVolumes is now deprecated in favor of workers.celery.extraVolumes/workers.kubernetes.extraVolumes (#64746).
  • workers.affinity is now deprecated in favor of workers.celery.affinity/workers.kubernetes.affinity (#64860).
  • workers.tolerations is now deprecated in favor of workers.celery.tolerations/workers.kubernetes.tolerations (#64976).
  • workers.topologySpreadConstraints is now deprecated in favor of workers.celery.topologySpreadConstraints/workers.kubernetes.topologySpreadConstraints (#64980).
  • workers.podAnnotations is now deprecated in favor of workers.celery.podAnnotations/workers.kubernetes.podAnnotations (#65027).
  • workers.labels is now deprecated in favor of workers.celery.labels/workers.kubernetes.labels (#65030).
  • workers.env is now deprecated in favor of workers.celery.env/workers.kubernetes.env (#65056).
  • workers.extraVolumeMounts is now deprecated in favor of workers.celery.extraVolumeMounts/workers.kubernetes.extraVolumeMounts (#65059).
  • workers.extraPorts is now deprecated in favor of workers.celery.extraPorts (#61919).
  • workers.volumeClaimTemplates is now deprecated in favor of workers.celery.volumeClaimTemplates (#62048).
  • workers.waitForMigrations is now deprecated in favor of workers.celery.waitForMigrations (#62054).
  • workers.hpa is now deprecated in favor of workers.celery.hpa (#64734).
  • workers.annotations is now deprecated in favor of workers.celery.annotations (#64982).
  • workers.logGroomerSidecar is now deprecated in favor of workers.celery.logGroomerSidecar (#65033).

The previous configuration options are still working but are deprecated and will be removed in a future version.

Default Airflow image is updated to 3.2.0 (#64841)

The default Airflow image that is used with the Chart is now 3.2.0, previously it was 3.1.8.

New Features

  • Add ttlSecondsAfterFinished to database cleanup job (#64164)
  • Support tpl rendering in ServiceAccount annotations, metadataConnection, and config ConfigMap names (#64763)

Improvements

  • Generate JWT Secret of recommended length (#65082)

Bug Fixes

  • Fix wrong broker URL secret ref (#65006)
  • Fix Helm chart image volume schema validation (#65409)
  • Remove duplicate fallback branch in airflowPodSecurityContextsIds helper (#65558)
  • Render cleanup RBAC only for KubernetesExecutor (#65539)
  • Fix default args/command for database cleanup (#63821)
  • Fix invalid deprecation warning in NOTES.txt (#64296)
  • Add missing fields in schema file (#64339)

Doc only changes

  • Document secret key names for Helm chart secretName options (#64136)
  • Update customizing-labels documentation (#64170)
  • Fix documentation link (#64355)

Misc

  • Simplify Helm Chart Logic & Misc (#63957)
  • Improve consistency of values.yaml & misc (#64559)
  • Align log_id_template with current default in Elasticsearch provider (#64332)
  • Update alpine version in pgbouncer and pgbouncer-exporter (#65413)
  • Add default GO_VERSION for pgbouncer-exporter Dockerfile (#65446)
3.2.1 Breaking risk
⚠ Upgrade required
  • Update custom user roles to include read access for DAG Runs, Task Instances, and HITL Details if those users should retain /dags endpoint access.
Breaking changes
  • /dags endpoint now requires DagAccessEntity.RUN, DagAccessEntity.HITL_DETAIL, and DagAccessEntity.TASK_INSTANCE permissions; read‑only access is no longer sufficient.
Notable features
  • UI theme configuration supports optional `tokens` field to restore OSS defaults
  • Add `write_to_os` support for writing task logs to OpenSearch
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow/3.2.1/
📚 Docs: https://airflow.apache.org/docs/apache-airflow/3.2.1/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow/3.2.1/release_notes.html
🐳 Docker Image: "docker pull apache/airflow:3.2.1"
🚏 Constraints: https://github.com/apache/airflow/tree/constraints-3.2.1

Significant Changes

  • Users who only have read access to DAGs will no longer be able to fetch data from the /dags endpoint, as it now requires additional permissions (DagAccessEntity.RUN, DagAccessEntity.HITL_DETAIL, and DagAccessEntity.TASK_INSTANCE). This change was made because the endpoint returns aggregated data from these multiple entities. Please update your custom user roles to include read access for DAG Runs, Task Instances, and HITL Details if those users should still have access to the /dags endpoint. (#64822)

Improvements

  • Allow UI theme config with only CSS overrides, icon only, or empty {} to restore OSS defaults. The tokens field is now optional in the theme configuration. (#64552)

Bug Fixes

  • Fix DEFAULT_LOGGING_CONFIG to use right kwargs (#65412) (#65424)
  • Fix zip DAG import errors being cleared during bundle refresh (#63617) (#65296)
  • Fix dispose_orm() not disposing async engine on shutdown (#65274) (#65284)
  • Fix get_team_name_dep creating wasted async sessions when multi_team=False (#65275) (#65282)
  • Fix asset graph view leaking DAGs outside the user's permissions (#65273) (#65280)
  • Fix migration: add missing disable_sqlite_fkeys to migration 0108 (#65288) (#65290)
  • Fix heartbeat: add fast-path UPDATE to avoid row lock in the common case (#65029) (#65137)
  • UI: Fix deactivated state not shown for stale DAGs (#65214) (#65218)
  • Fix N+1 queries during DAG serialization with bulk prefetch (#64929) (#65208)
  • Fix serializer for empty string extra in connection (#65014) (#65215)
  • UI: Fix menu positioning for dropdowns in connection forms (#65007) (#65085) (#65138)
  • UI: Fix SearchBar value not syncing with defaultValue changes (#65054) (#65140)
  • Fix SDK configuration to use $AIRFLOW_CONFIG env (#64936) (#65200)
  • Fix Session staying opened between yields (#65179) (#65195)
  • Fix Session leak from StreamingResponse API endpoints (#65162) (#65193)
  • Fix redirect loop when stale root-path _token cookie exists from older Airflow instance (#64955) (#65177)
  • Fix @task decorator to validate operator arg types at decoration time (#65041) (#65050)
  • Fix CLI error handling and exit codes for failed commands (#65052) (#65097)
  • Fix is_alive default to None in jobs list CLI (#65065) (#65091)
  • Fix missing dag_id in get_task_instance (#64957) (#64968) (#65067)
  • UI: Fix cancel debounce on clear to prevent stale search value (#64893) (#64907)
  • Fix read out-of-order issue with send method in CommsDecoder (#64894) (#64946)
  • Fix bulk connection delete banner (#64735) (#64961)
  • Fix migrations: move UPDATEs inside disable_sqlite_fkeys in migration 0097 (#64876) (#64940)
  • Fix heartbeat to return 410 Gone when cleared TI exists in TIH (#61631) (#64693)
  • Fix scheduler: skip asset-triggered Dags without SerializedDagModel (#64322) (#64738)
  • Fix N+1 query pattern in task instance states and count endpoints (#60352) (#64695)
  • Fix TypeError in GET /dags/{dag_id}/tasks when order_by field has None values (#64384) (#64587)
  • UI: Fix duplicate nav sidebar when iframe navigates away from auth pages (#63873) (#64854)
  • UI: Fix Gantt view "Error invalid date" on running DagRun (#64752) (#64853)
  • Fix connections import returning non-zero exit code on failure (#64416) (#64449)
  • Fix structlog positional formatting for single-dict arguments (#62849) (#64773)
  • UI: Fix external link target and add rel attributes (#64542) (#64772)
  • UI: Fix DagVersionSelect options not filtered by selected DagRun (#64736) (#64771)
  • Fix spurious blank lines in filtered task log download (#64235) (#64640)
  • Fix OTel metrics lost in forked task processes (#64703) (#64720)
  • Fix start_date in example DAGs to avoid timezone conversion overflow (#63882) (#64758)
  • Fix AirflowPlugin not re-exported, causing mypy errors in plugins (#65132) (#65163)
  • Fix apache-airflow-providers-fab minimum version to prevent connexion import error on Python 3.13 (#65523) (#65524)
  • UI: Fix graph view not auto-refreshing task states during DAG run (#65518) (#65522)

Miscellaneous

  • Lock TriggerCommsDecoder sync req-res cycle (#64882) (#65285)
  • Add write_to_os support for writing task logs to OpenSearch (#64364) (#65201)
  • Restore OpenSearch log integration in airflow_local_settings.py (#64764) (#65003)

Doc-only Changes

  • Add missing Polish translations to reach 100% coverage (#65272)
  • Add FAQ entry for API server memory growth with gunicorn worker recycling (#65036) (#65037)
  • Remove outdated reference to Dag Dependencies view (#64787) (#64911)
  • Add JWT authentication docs and strengthen security model (#64760) (#64849)
  • Add missing Catalan translations to reach 100% coverage (#65078) (#65389)
  • Add missing German translations to close translation gaps (#65332)
3.2.0 Breaking risk
⚠ Upgrade required
  • Asset partitioning requires updating Dag definitions to use new partition mappers and APIs.
  • Multi‑team deployments are experimental; behavior may change in future releases.
  • Deadline Alerts synchronous callbacks do not support Connections stored in the metadata DB.
Breaking changes
  • Removed ``airflow.traces`` internal OTel trace metaclass and shared tracer wrappers.
  • Removed legacy functions ``serialize()`` and ``deserialize()`` from experimental class ``PriorityWeightStrategy``.
  • Removed methods ``run()``, ``render_templates()``, ``get_template_context()`` and related private members from class ``TaskInstance``.
Notable features
  • Multi‑team deployments provide isolated teams within a single Airflow instance (experimental).
  • Synchronous callback support for Deadline Alerts via new ``SyncCallback`` (experimental).
  • UI enhancements: Grid view virtualization, XCom management UI, HITL detail history, Gantt chart improvements.
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow/3.2.0/
📚 Docs: https://airflow.apache.org/docs/apache-airflow/3.2.0/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow/3.2.0/release_notes.html
🐳 Docker Image: "docker pull apache/airflow:3.2.0"
🚏 Constraints: https://github.com/apache/airflow/tree/constraints-3.2.0

Significant Changes

Asset Partitioning

The headline feature of Airflow 3.2.0 is asset partitioning — a major evolution of data-aware
scheduling. Instead of triggering Dags based on an entire asset, you can now schedule downstream
processing based on specific partitions of data. Only the relevant slice of data triggers downstream
work, making pipeline orchestration far more efficient and precise.

This matters when working with partitioned data lakes — date-partitioned S3 paths, Hive table
partitions, BigQuery table partitions, or any other partitioned data store. Previously, any update
to an asset triggered all downstream Dags regardless of which partition changed. Now only the right
work gets triggered at the right time.

For detailed usage instructions, see :doc:/authoring-and-scheduling/assets.

Multi-Team Deployments

Airflow 3.2 introduces multi-team support, allowing organizations to run multiple isolated teams within a single Airflow deployment.
Each team can have its own Dags, connections, variables, pools, and executors— enabling true resource and permission isolation without requiring separate Airflow instances per team.

This is particularly valuable for platform teams that serve multiple data engineering or data science teams from shared infrastructure, while maintaining strong boundaries between teams' resources and access.

For detailed usage instructions, see :doc:/core-concepts/multi-team.

.. warning::

Multi-Team Deployments are experimental in 3.2.0 and may change in future versions based on
user feedback.

Synchronous callback support for Deadline Alerts

Deadline Alerts now support synchronous callbacks via SyncCallback in addition to the existing
asynchronous AsyncCallback. Synchronous callbacks are executed by the executor (rather than
the triggerer), and can optionally target a specific executor via the executor parameter.

A Dag can also define multiple Deadline Alerts by passing a list to the deadline parameter,
and each alert can use either callback type.

.. warning::

Deadline Alerts are experimental in 3.2.0 and may change in future versions based on
user feedback. Synchronous deadline callbacks (SyncCallback) do not currently
support Connections stored in the Airflow metadata database.

For detailed usage instructions, see :doc:/howto/deadline-alerts.

UI Enhancements & Performance

  • Grid View Virtualization:
    The Grid view now uses virtualization -- only visible rows are rendered to the DOM. This dramatically improves performance when viewing Dags with large numbers of task runs, reducing render time and memory usage for complex Dags. (#60241)

  • XCom Management in the UI:
    You can now add, edit, and delete XCom values directly from the Airflow UI. This makes it much easier to debug and manage XCom state during development and day-to-day operations without needing CLI commands. (#58921)

  • HITL Detail History:
    The Human-in-the-Loop approval interface now includes a full history view, letting operators and reviewers see the complete audit trail of approvals and rejections for any task. (#56760, #55952)

  • Gantt Chart Improvements:

    • All task tries displayed: Gantt chart now shows every attempt, not just the latest
    • Task display names in Gantt: task_display_name shown for better readability (#61438)
    • ISO dates in Gantt: Cross-browser consistent date format (#61250)
    • Fixed null datetime crash: Gantt chart no longer crashes on tasks with null datetime fields

New --only-idle flag for the scheduler CLI

The airflow scheduler command has a new --only-idle flag that only counts runs when the
scheduler is idle. This helps users run the scheduler once and process all triggered Dags and
queued tasks. It requires and complements the --num-runs flag so one can set a small value
instead of guessing how many iterations the scheduler needs.

Replace per-run TI summary requests with a single NDJSON stream

The grid, graph, gantt, and task-detail views now fetch task-instance
summaries through a single streaming HTTP request
(GET /ui/grid/ti_summaries/{dag_id}?run_ids=...) instead of one request
per run. The server emits one JSON line per run as soon as that run's task
instances are ready, so columns appear progressively rather than all at once.

What changed:

  • GET /ui/grid/ti_summaries/{dag_id}?run_ids=... is now the sole endpoint
    for TI summaries, returning an application/x-ndjson stream where each
    line is a serialized GridTISummaries object for one run.
  • The old single-run endpoint GET /ui/grid/ti_summaries/{dag_id}/{run_id}
    has been removed.
  • The serialized Dag structure is loaded once and shared across all runs that
    share the same dag_version_id, avoiding redundant deserialization.
  • All UI views (grid, graph, gantt, task instance, mapped task instance, group
    task instance) use the stream endpoint, passing one or more run_ids.

Structured JSON logging for all API server output

The new json_logs option under the [logging] section makes Airflow
produce all its output as newline-delimited JSON (structured logs) instead of
human-readable formatted logs. This covers the API server (gunicorn/uvicorn),
including access logs, warnings, and unhandled exceptions.

Not all components support this yet — notably airflow celery worker but
any non-JSON output when json_logs is enabled will be treated as a bug. (#63365)

Remove legacy OTel Trace metaclass and shared tracer wrappers

The interfaces and functions located in airflow.traces were
internal code that provided a standard way to manage spans in
internal Airflow code. They were not intended as user-facing code
and were never documented. They are no longer needed so we
remove them in 3.2. (#63452)

Move task-level exception imports into the Task SDK

Airflow now sources task-facing exceptions (AirflowSkipException, TaskDeferred, etc.) from
airflow.sdk.exceptions. airflow.exceptions still exposes the same exceptions, but they are
proxies that emit DeprecatedImportWarning so Dag authors can migrate before the shim is removed.

What changed:

  • Runtime code now consistently raises the SDK versions of task-level exceptions.
  • The Task SDK redefines these classes so workers no longer depend on airflow-core at runtime.
  • airflow.providers.common.compat.sdk centralizes compatibility imports for providers.

Behaviour changes:

  • Sensors and other helpers that validate user input now raise ValueError (instead of
    AirflowException) when poke_interval/ timeout arguments are invalid.
  • Importing deprecated exception names from airflow.exceptions logs a warning directing users to
    the SDK import path.

Exceptions now provided by airflow.sdk.exceptions:

  • AirflowException and AirflowNotFoundException
  • AirflowRescheduleException and AirflowSensorTimeout
  • AirflowSkipException, AirflowFailException, AirflowTaskTimeout, AirflowTaskTerminated
  • TaskDeferred, TaskDeferralTimeout, TaskDeferralError
  • DagRunTriggerException and DownstreamTasksSkipped
  • AirflowDagCycleException and AirflowInactiveAssetInInletOrOutletException
  • ParamValidationError, DuplicateTaskIdFound, TaskAlreadyInTaskGroup, TaskNotFound, XComNotFound
  • AirflowOptionalProviderFeatureException

Backward compatibility:

  • Existing Dags/operators that still import from airflow.exceptions continue to work, though
    they log warnings.
  • Providers can rely on airflow.providers.common.compat.sdk to keep one import path that works
    across supported Airflow versions.

Migration:

  • Update custom operators, sensors, and extensions to import exception classes from
    airflow.sdk.exceptions (or from the provider compat shim).
  • Adjust custom validation code to expect ValueError for invalid sensor arguments if it
    previously caught AirflowException.

Support numeric multiplier values for retry_exponential_backoff parameter

The retry_exponential_backoff parameter now accepts numeric values to specify custom exponential backoff multipliers for task retries. Previously, this parameter only accepted boolean values (True or False), with True using a hardcoded multiplier of 2.0.

New behavior:

  • Numeric values (e.g., 2.0, 3.5) directly specify the exponential backoff multiplier
  • retry_exponential_backoff=2.0 doubles the delay between each retry attempt
  • retry_exponential_backoff=0 or False disables exponential backoff (uses fixed retry_delay)

Backwards compatibility:

Existing Dags using boolean values continue to work:

  • retry_exponential_backoff=True → converted to 2.0 (maintains original behavior)
  • retry_exponential_backoff=False → converted to 0.0 (no exponential backoff)

API changes:

The REST API schema for retry_exponential_backoff has changed from type: boolean to type: number. API clients must use numeric values (boolean values will be rejected).

Migration:

While boolean values in Python Dags are automatically converted for backwards compatibility, we recommend updating to explicit numeric values for clarity:

  • Change retry_exponential_backoff=Trueretry_exponential_backoff=2.0
  • Change retry_exponential_backoff=Falseretry_exponential_backoff=0

Move serialization/deserialization (serde) logic into Task SDK

Airflow now sources serde logic from airflow.sdk.serde instead of
airflow.serialization.serde. Serializer modules have moved from airflow.serialization.serializers.*
to airflow.sdk.serde.serializers.*. The old import paths still work but emit DeprecatedImportWarning
to guide migration. The backward compatibility layer will be removed in Airflow 4.

What changed:

  • Serialization/deserialization code moved from airflow-core to task-sdk package
  • Serializer modules moved from airflow.serialization.serializers.* to airflow.sdk.serde.serializers.*
  • New serializers should be added to airflow.sdk.serde.serializers.* namespace

Code interface changes:

  • Import serializers from airflow.sdk.serde.serializers.* instead of airflow.serialization.serializers.*
  • Import serialization functions from airflow.sdk.serde instead of airflow.serialization.serde

Backward compatibility:

  • Existing serializers importing from airflow.serialization.serializers.* continue to work with deprecation warnings
  • All existing serializers (builtin, datetime, pandas, numpy, etc.) are available at the new location

Migration:

  • For existing custom serializers: Update imports to use airflow.sdk.serde.serializers.*
  • For new serializers: Add them to airflow.sdk.serde.serializers.* namespace (e.g., create task-sdk/src/airflow/sdk/serde/serializers/your_serializer.py)

Methods removed from PriorityWeightStrategy

On (experimental) class PriorityWeightStrategy, functions serialize()
and deserialize() were never used anywhere, and have been removed. They
should not be relied on in user code. (#59780)

Methods removed from TaskInstance

On class TaskInstance, functions run(), render_templates(),
get_template_context(), and private members related to them have been
removed. The class has been considered internal since 3.0, and should not be
relied on in user code. (#59780, #59835)

Modify the information returned by DagBag

New behavior:

  • DagBag now uses Path.relative_to for consistent cross-platform behavior.
  • FileLoadStat now has two additional nullable fields: bundle_path and bundle_name.

Backward compatibility:

FileLoadStat will no longer produce paths beginning with / with the meaning of "relative to the dags folder".
This is a breaking change for any custom code that performs string-based path manipulations relying on this behavior.
Users are advised to update such code to use pathlib.Path. (#59785)

Remove --conn-id option from airflow connections list

The redundant --conn-id option has been removed from the airflow connections list CLI command.
Use airflow connections get instead. (#59855)

Add operator-level render_template_as_native_obj override

Operators can now override the Dag-level render_template_as_native_obj setting,
enabling fine-grained control over whether templates are rendered as native Python
types or strings on a per-task basis. Set render_template_as_native_obj=True or
False on any operator to override the Dag setting, or leave as None (default)
to inherit from the Dag.

Add gunicorn support for API server with zero-downtime worker recycling

The API server now supports gunicorn as an alternative server with rolling worker restarts
to prevent memory accumulation in long-running processes.

Key Benefits:

  • Rolling worker restarts: New workers spawn and pass health checks before old workers
    are killed, ensuring zero downtime during worker recycling.

  • Memory sharing: Gunicorn uses preload + fork, so workers share memory via
    copy-on-write. This significantly reduces total memory usage compared to uvicorn's
    multiprocess mode where each worker loads everything independently.

  • Correct FIFO signal handling: Gunicorn's SIGTTOU kills the oldest worker (FIFO),
    not the newest (LIFO), which is correct for rolling restarts.

Configuration:

.. code-block:: ini

[api]
# Use gunicorn instead of uvicorn
server_type = gunicorn

# Enable rolling worker restarts every 12 hours
worker_refresh_interval = 43200

# Restart workers one at a time
worker_refresh_batch_size = 1

Or via environment variables:

.. code-block:: bash

export AIRFLOW__API__SERVER_TYPE=gunicorn
export AIRFLOW__API__WORKER_REFRESH_INTERVAL=43200

Requirements:

Install the gunicorn extra: pip install 'apache-airflow-core[gunicorn]'

Note on uvicorn (default):

The default uvicorn mode does not support rolling worker restarts because:

  1. With workers=1, there is no master process to send signals to
  2. uvicorn's SIGTTOU kills the newest worker (LIFO), defeating rolling restart purposes
  3. Each uvicorn worker loads everything independently with no memory sharing

If you need worker recycling or memory-efficient multi-worker deployment, use gunicorn. (#60921)

Improved performance of rendered task instance fields cleanup for Dags with many mapped tasks (~42x faster)

The config max_num_rendered_ti_fields_per_task is renamed to num_dag_runs_to_retain_rendered_fields
(old name still works with deprecation warning).

Retention is now based on the N most recent dag runs rather than N most recent task executions,
which may result in fewer records retained for conditional/sparse tasks. (#60951)

AuthManager Backfill permissions are now handled by the requires_access_dag on the DagAccessEntity.Run

is_authorized_backfill of the BaseAuthManager interface has been removed. Core will no longer call this method and their
provider counterpart implementation will be marked as deprecated.
Permissions for backfill operations are now checked against the DagAccessEntity.Run permission using the existing
requires_access_dag decorator. In other words, if a user has permission to run a Dag, they can perform backfill operations on it.

Please update your security policies to ensure that users who need to perform backfill operations have the appropriate DagAccessEntity.Run permissions. (Users
having the Backfill permissions without having the DagRun ones will no longer be able to perform backfill operations without any update)

Python 3.14 support added

Airflow 3.2.0 adds support for Python 3.14. (#63787)

Reduce API server memory by eliminating SerializedDAG loads on task start

The API server no longer loads the full SerializedDAG when starting tasks,
significantly reducing memory usage. (#60803)

Remove MySQL client from container images

MySQL client support has been removed from official Airflow container images. MySQL users
building on official images must install the client themselves. (#57146)

Add support for async callables in PythonOperator

The PythonOperator parameter python_callable now also supports async callables in Airflow 3.2,
allowing users to run async def functions without manually managing an event loop. (#60268)

Make start_date optional for @continuous schedule

The schedule="@continuous" parameter now works without requiring a start_date, and any Dags with this schedule will begin running immediately when unpaused. (#61405)

New Features

  • Add FIPS support by making Python LTO configurable via PYTHON_LTO build argument (#58337)
  • Add support for task queue-based Trigger assignment to specific Triggerer hosts via the new --queues CLI option for the trigger command (#59239)
  • Add --show-values and --hide-sensitive flags to CLI connections list and variables list to hide sensitive values by default (#62344)
  • Add support for setting individual secrets backend kwargs via AIRFLOW__SECRETS__BACKEND_KWARG__<KEY> environment variables (#63312)
  • Add only_new parameter to Dag clear to only clear newly added task instances (#59764)
  • Add log_timestamp_format config option for customizing component log timestamps (#63321)
  • Add --action-on-existing-key option to pools import and connections import CLI commands (#62702)
  • Add back --use-migration-files flag for airflow db init (#62234)
  • Add AllowedKeyMapper for partition key validation in asset partitioning (#61931)
  • Add ChainMapper for chaining multiple partition mappers (#64094)
  • Add cryptographic signature verification for Python source packages in Docker builds (#63345)
  • Add Human-in-the-Loop (HITL) Review system for AgenticOperator (#63081)
  • Add @task.stub decorator to allow tasks in other languages to be defined in Dags (#56055)
  • Add support for creating connections using URI in SDK (#62211)
  • Add note support to TriggerDagRunOperator (#60810)
  • Add allowed_run_types to whitelist specific Dag run types (#61833)
  • Add OR operator support in API search parameters (#60008)
  • Add API filtering for Dags by timetable type (#58852)
  • Add wildcard support for dag_id and dag_run_id in bulk task instance endpoint (#57441)
  • Add operator_name_pattern, pool_pattern, queue_pattern as task instance search filters (#57571)
  • Add update_mask support for bulk PATCH APIs (#54597)
  • Add asset event emission listener event (#61718)
  • Add source parameter to Param (#58615)
  • Add lazy filtering for inlet events by time range, ordering, and limit (#54891)
  • Add ability to get previous TaskInstance on RuntimeTaskInstance (#59712)
  • Add required context messages to all DagRun state change notifications (#56272)
  • Add max_trigger_to_select_per_loop config for Triggerer HA setup (#58803)
  • Add uvicorn_logging_level config option to control API server access logs (#56062)
  • Add correlation-id support to Execution API for request tracing (#57458)
  • Add executor.running_dags gauge metric to expose count of running Dags (#52815)
  • Add submodules support to GitDagBundle (#59911)
  • Add HTTP URL authentication support to GitHook for Dag bundles (#58194)
  • Add stream method to RemoteIO for ObjectStorage (#54813)
  • Add CLI hot-reload support via --dev flag (#57741)
  • Add auth list-envs command to list CLI environments and auth status (#61426)
  • Add Dag bundles to airflow info command output (#59124)
  • Add new arguments to db_clean to explicitly include or exclude Dags (#56663)
  • UI: Add Jobs page to the Airflow UI (#61512)
  • UI: Add version change indicators for Dag and bundle versions in Grid view (#53216)
  • UI: Add segmented state bar for collapsed task groups and mapped tasks (#61854)
  • UI: Add date range filter for Dag executions (#60772)
  • UI: Add "Select Recent Configurations" to trigger form, restoring Airflow 2 functionality (#56406)
  • UI: Add copy button to logs (#61185)
  • UI: Add filename display to Dag Code tab for easier file identification (#60759)
  • UI: Add Dag run state filter to grid view options (#55898)
  • UI: Add task upstream/downstream filter to Graph and Grid views (#57237)
  • UI: Add filters to Task Instances tab (#56920)
  • UI: Add display of active Dag runs count in header with auto-refresh (#58332)
  • UI: Add Dag ID pattern search to Dag Runs and Task Instances pages (#55691)
  • UI: Add delete button for Dag runs in more options menu (#55696)
  • UI: Add depth filter to TaskStreamFilter (#60549)
  • UI: Add theme config support (#58411)
  • UI: Add support for globalCss in custom themes (#61161)
  • UI: Add display of logged-in user in settings button (#58981)
  • UI: Add tooltip for explaining task filter traversal (#61401)
  • UI: Add self-service JWT token generation for API and CLI access (#63195)
  • UI: Add bulk operations for edge workers page (#64033)
  • UI: Add real-time concurrency control for edge workers (#63142)
  • UI: Add run_after date filter on Dag runs page (#62797)
  • UI: Add bundle version filter on Dag runs page (#62810)
  • UI: Add icon support for theme customization (#62172)
  • UI: Add Monaco editor for all JSON editing fields (#62708)
  • UI: Add run type legend tooltip to grid view (#62946)
  • UI: Allow customizing gray, black, and white color tokens in AIRFLOW__API__THEME in addition to brand (#64232)

Bug Fixes

  • Fix sensitive configuration values not being masked in public config APIs; treat the deprecated non-sensitive-only value as True (#59880)
  • Fix InvalidStatsNameException for pool names with invalid characters by auto-normalizing them when emitting metrics (#59938)
  • Fix JWT tokens appearing in task logs by excluding the token field from workload object representations (#62964)
  • Fix security iframe navigation when AIRFLOW__API__BASE_URL basename is configured (#63141)
  • Fix grid view URL for dynamic task groups producing 404 by not appending /mapped to group URLs (#63205)
  • Fix ti_skip_downstream overwriting RUNNING tasks to SKIPPED in HA deployments (#63266)
  • Fix duplicate task execution when running multiple schedulers (#60330)
  • Fix callback starvation across Dag bundles (#63795)
  • Fix @task decorator failing for tasks that return falsy values like 0 or empty string (#63788)
  • Fix LatestOnlyOperator not working when direct upstream of a dynamically mapped task (#62287)
  • Fix inconsistent XCom return type in mapped task groups with dynamic mapping (#59104)
  • Fix task group lookup using wrong Dag version for historical runs, causing 404 errors in grid view (#63360)
  • Fix import errors when updating Dags in other bundles (#63615)
  • Fix DagRun span emission crash when context_carrier is None (#64087)
  • Fix false error logs for partitioned timetables when next_dagrun fields are None (#63962)
  • Fix timetable serialization error when decoding relativedelta (#61671)
  • Fix task_instance_mutation_hook receiving run_id=None during TaskInstance creation (#63049)
  • Fix scheduler crash on None dag_version access (#62225)
  • Fix MetastoreBackend.expunge_all() corrupting shared session state (#63080)
  • Fix triggerer logger file descriptor closed prematurely when trigger is removed (#62103)
  • Fix airflowignore negation pattern handling for directory-only patterns (#62860)
  • Fix false warnings for TYPE_CHECKING-only forward references in TaskFlow decorators (#63053)
  • Fix structlog JSON serialization crash on non-serializable objects (#62656)
  • Fix backward compatibility for deadline alert serialization (#63701)
  • Fix queued_tasks type mismatch in hybrid executors (CeleryKubernetesExecutor, LocalKubernetesExecutor) (#63744)
  • Fix Celery tasks not being registered at worker startup (#63110)
  • Fix asset partition detection incorrectly identifying Dags as partitioned (#62864)
  • Fix pathlib.Path objects incorrectly resolved by Jinja templater in Task SDK (#63306)
  • Fix state mismatch in Kubernetes executor after pod completion (#63061)
  • Fix make_partial_model for API Pydantic models (#63716)
  • Fix WTForms validator compatibility in connection form (#63823)
  • Fix _execution_api_server_url() ignoring configured value and falling back to edge config (#63192)
  • Fix DetachedInstanceError for airflow tasks render command (#63916)
  • Fix scheduler isolating per-dag-run failures to prevent a single DagRun crashing all scheduling (#62893)
  • Fix task argument order in @task definition causing Dag parsing errors (#62174)
  • Fix limit parameter not sent in execute_list server requests (#63048)
  • Fix circular import from airflow.configuration causing ImportError on Python 3.14 (#63787)
  • Fix map_index range validation in CLI commands (#62626)
  • Fix nullable ORM fields by restoring correct defaults and dropping unreleased corrective migration (#63899)
  • Fix race condition in auth manager initialization on concurrent requests (#62431)
  • Fix FabAuthManager race condition on startup with multiple workers (#62737)
  • Fix FabAuthManager race condition when workers concurrently create permissions, roles, and resources (#63842)
  • Fix JWTValidator not handling GUESS algorithm with JWKS (#63115)
  • Fix FabAuthManager first idle MySQL disconnect in token auth (#62919)
  • Fix JWTBearerTIPathDep import errors in Human-In-The-Loop routes (#63277)
  • Fix 403 from roles endpoint despite admin rights in FAB provider (#64097)
  • Fix task log filters not working in full-screen mode (#62747)
  • Fix duplicate log reads when resuming from log_pos (#63531)
  • Fix 404 errors from worker log server for historical retry attempts now handled gracefully (#62475)
  • Fix Elasticsearch/OpenSearch logging exception details missing in task log tab (#63739)
  • Fix task-level audit logs missing success/running events (#61932)
  • Fix null dag_run_conf causing serialization error in BackfillResponse (#63259)
  • Fix CLI asset materialization using wrong Dag run type (#63815)
  • Fix migration 0094 performance: use SQL instead of Python deserialization (#63628)
  • Fix migration reliability: replace savepoints with per-Dag transactions (#63591)
  • Fix slow downgrade performance by adding index to deadline.callback_id (#63612)
  • Fix MySQL reserved keyword interval causing query failures in deadline_alert (#63494)
  • Fix MySQL serialize_dag query failure during deadline migration (#63804)
  • Fix SQLite downgrade failures caused by FK constraints during batch table recreation (#63437)
  • Fix migration 0096 downgrade failing when team table has existing rows (#63449)
  • Fix missing warning about hardcoded 24h visibility_timeout that kills long-running Celery tasks (#62869)
  • Fix scheduler memory issue by removing eager loading of all task instances (#60956)
  • Fix MySQL sort buffer overflow in deadline alert migration (#61806)
  • Fix failing to manually trigger a Dag with CronPartitionedTimetable (#62441)
  • Fix race condition in AssetModel when updating asset partition DagRun — adds mutex lock (#59183)
  • Fix FAB auth_manager load_user causing PendingRollbackError (#61943)
  • Fix N+1 query: add joinedload for asset in dags_needing_dagruns() (#60957)
  • Fix Dag Processor health check threshold matching SchedulerJob/TriggererJob pattern (#58704)
  • Fix NotMapped exception when clearing task instances with downstream/upstream (#58922)
  • Fix missing asset events for partitioned DagRun (#61433)
  • Fix missing partition_key filter in PALK when creating DagRun (#61831)
  • Fix Dag params API contract broken by earlier change (#56831)
  • Fix OAuth session race condition causing false 401 errors during login (#61287)
  • Fix ObjectStoragePath to exclude conn_id from storage options passed to fsspec (#62701)
  • Fix unable to import list value for Variable (#61508)
  • Fix plugin registration returning early on duplicate names (#60498)
  • Fix circular import when using XComObjectStorageBackend (#55805)
  • Fix deadline alert hashing bug (#61702)
  • Fix task SDK to read default_email_on_failure/default_email_on_retry from config (#59912)
  • Fix Celery worker crash on macOS due to non-serializable local function (#62655)
  • Fix Redis import race condition in Celery executor (#61362)
  • Fix incorrect state query parameter for task instances in Dashboard (#59086)
  • Fix TaskInstance.get_dagrun returning None in task_instance_mutation_hook (#60726)
  • Fix Simple Auth Manager login showing cryptic error on failed authentication (#64303)
  • Fix dag_display_name property bypass for DagStats query (#64256)
  • Fix TaskAlreadyRunningError not raised when starting an already-running task instance (#60855)
  • Fix Teardown tasks not waiting for all in-scope tasks to complete (#64181)
  • Fix enable_swagger_ui config not respected in API server (#64376)
  • Fix: add check for xcom permission when result is specified for DagRun wait endpoint (#64415)
  • Fix conf.has_option not respects default provider metadata (#64209)
  • Fix teardown scope causing unnecessary database writes during task scheduling (#64558)
  • Fix live task log output not visible in stdout when using Elasticsearch log forwarding (#64067)
  • Fix TaskInstance crash when refreshing task weight for non-serialized operators (#64557)
  • Fix Variables secrets backend conflict check exiting early when multiple backends are configured (#64062)
  • UI: Fix Dag run accessor key on clear task instance page (#64072)
  • UI: Fix searchable dropdown not working for Dag params enum fields (#63895)
  • UI: Fix newline rendering in Dag warning alert (#63588)
  • UI: Fix XCom edit modal value not repopulating on reopen (#62798)
  • UI: Fix task duration tooltip not displaying correctly (#63639)
  • UI: Fix elapsed time not showing for running tasks (#63619)
  • UI: Fix RenderedJsonField collapse behavior (#63831)
  • UI: Fix RenderedJsonField not displaying in table cells (#63245)
  • UI: Fix full-screen log dropdown z-index after Chakra upgrade (#63816)
  • UI: Fix asset materialization run type display (#63819)
  • UI: Fix pools with unlimited (-1) slots not rendering correctly (#62831)
  • UI: Fix DurationChart labels and disable animation flicker during auto-refresh (#62835)
  • UI: Fix 403 error not shown when unauthorized user re-parses Dag (#61560)
  • UI: Fix logical date filter on /dagruns page not working (#62848)
  • UI: Fix inflated total_received count in partitioned Dag runs view (#62786)
  • UI: Fix edge executor navigation when behind reverse proxy with subpath (#63777)
  • UI: Fix queries not invalidated on Dag run add/delete (#64269)
  • UI: Fix RenderedJsonField flickering when collapsed (#64261)
  • UI: Fix Docs menu REST API link visibility when API docs are disabled (#64359)
  • UI: Fix TISummaries not refreshing when gridRuns are invalidated (#64113)
  • UI: Fix guard against null/undefined dates in Gantt chart to prevent RangeError (#64031)
  • UI: Block polling requests to endpoints that returned 403 Forbidden (#64333)
  • UI: Fix Gantt view still visible when time range is outside DagRun window (#64179)
  • UI: Fix Human-in-the-Loop (HITL) operator options not displaying when exactly 4 choices are configured (#64453)

Miscellaneous

  • Deprecate api.page_size config in favor of api.fallback_page_limit (#61067)
  • Improve Dag callback relevancy by passing a context-relevant task instance based on the Dag's final state instead of an arbitrary lexicographical selection (#61274)
  • Optimize get_dag_runs API endpoint performance (#63940)
  • Improve historical metrics endpoint performance (#63526)
  • Add TTL cache with single-flight deduplication to Keycloak filter_authorized_dag_ids (#63184)
  • Reduce Celery worker memory usage with gc.freeze (#62212)
  • Eliminate duplicate JOINs in get_task_instances endpoint (#62910)
  • Replace large IN clause in asset queries with CTE and JOIN for better SQL performance (#62114)
  • Add row lock to prevent race conditions during asset-triggered DagRun creation (#60773)
  • Add ConnectionResponse serializer safeguard to prevent accidental sensitive field exposure (#63883)
  • Add missing dag_id filter on DagRun task instances API query (#62750)
  • Add missing HTTP timeout to FAB JWKS fetching (#63058)
  • Add additional permission check in asset materialization endpoint (#63338)
  • Filter backfills list by readable Dags (authorization enforcement) (#63003)
  • Hide SQL statements in exception details when expose_stacktrace is disabled (#63028)
  • Use default max depth to redact Variable values in API responses (#63480)
  • Validate update_mask fields in PATCH API endpoints against Pydantic models (#62657)
  • Align key/id path validation for variables and connections in Execution API (#63897)
  • Add order_by parameter to GET /permissions endpoint for pagination consistency (#63418)
  • Implement truncation logic for rendered template values (#61878)
  • Add BaseXcom to airflow.sdk public exports (#63116)
  • Make TaskSDK conf respect default config from provider metadata (#62696)
  • Add OTel trace import shim via airflow.sdk.observability.trace (#63554)
  • Improve 3.2.0 deadline migration performance (#63920)
  • Improve 3.2.0 downgrade migration for external_executor_id on PostgreSQL (#63625)
  • Skip backfilling old DagRun.created_at during migration for faster upgrades (#63825)
  • Add INFO-level logging to asset scheduling path (#63958)
  • Improve log file template for ExecuteCallback by including dag_id and run_id (#62616)
  • Improve Dag processor timeout logging clarity (#62328)
  • Deprecate get_connection_form_widgets and get_ui_field_behaviour hook methods (#63711)
  • Add missing deprecation warnings for [workers] config section (#63659)
  • Expose TaskInstance API for external task management (#61568)
  • Remove deprecated airflow.datasets, airflow.timetables.datasets, and airflow.utils.dag_parsing_context modules (#62927)
  • Remove PyOpenSSL from core dependencies (#63869)
  • Optimize fail-fast check to avoid loading SerializedDAG (#56694)
  • Improve performance of task queue processing by switching from pop(0) to popleft() (#61376)
  • Optimize K8s API usage for watching pod events, fixing hanging communication (#59080)
  • Remove N+1 database queries for team names (#61471)
  • Improve XCom value handling in extra links API (#61641)
  • Remove .git folder from versions in GitDagBundle to reduce storage size (#57069)
  • Deprecate subprocess exec utils from airflow.utils.process_utils (#57193)
  • Improve error handling in edge worker on 405 responses (#60425)
  • Improve deferrable KubernetesPodOperator handling of deleted pods between polls (#56976)
  • Improve event log entries when a pod fails for K8s executor (#60800)
  • Refactor XCom API to use shared serialization constants (#64148)
  • Improve temporal mapper to be timezone aware for asset partitioning (#62709)
  • Improve dag version inflation checker logic and fix false-positive detection (#61345)
  • Rename ToXXXMapper to StartOfXXXMapper in partition-mapper for clarity (#64160)
  • Run DB check only for core components in prod entrypoint (#63413)
  • Fix partitioned asset events incorrectly triggering non-partition-aware Dags (#63848)
  • Improve partitioned DagRun sorting by partition_date (#62866)
  • Allow gray, black, and white color tokens in AIRFLOW__API__THEME config (#64232)
  • Add parent task spans and nest worker/trigger spans for improved observability (#63839)
  • UI: Enhance code view to support search and diff (#55467)
  • UI: Improve UX for adding custom DeadlineReferences (#57222)
  • UI: Enhance FilterBar with DateRangeFilter for compact UI (#56173)
  • UI: Move deadline alerts into their own table for UI integration (#58248)
  • UI: Persist tag filter selection in Dag grid view (#63273)
  • UI: Show HITL review tab only for review-enabled task instances (#63477)
  • UI: Updated button styles for adding Connections, Variables, and Pools (#62607)
  • UI: Add clear permission toast for 403 errors on user actions (#61588)

Doc Only Changes

  • Add documentation marking pre/post-execute task hooks as GA (no longer experimental) (#59656)
  • Add RedisTaskHandler configuration example (#63898)
  • Add documentation explaining difference between deferred vs async operators (#63500)
  • Add auth manager section in multi-team documentation (#63208)
  • Add documentation about shared libraries in _shared folders (#63468)
  • Clarify plugin folder module registration in modules_management docs (#63634)
  • Clarify max_active_tasks Dag parameter documentation (#63217)
  • Clarify HLL in extraction precedence docs (#63723)
  • Clarify Ubuntu/Debian venv requirement in quick start guide (#63244)
  • Fix Git connection docs to match actual GitHook parameters (#63265)
  • Mention Python 3.14 support in docs (#63950)
  • Add Dag documentation for example_bash_decorator (#62948)
  • Add Russian translation for UI (#63450)
  • Add Hungarian translation (#62925)
  • Complete Traditional Chinese translations (#62652)
  • Add asset partition documentation (#63262)
  • Add guide for dag version inflation and its checker (#64100)
helm-chart/1.20.0 Breaking risk
⚠ Upgrade required
  • Environment variables intended for specific components are no longer automatically propagated to Kubernetes Executor worker pods; use .Values.env or .Values.config.kubernetes_environment_variables instead.
  • Deprecation warnings added for per-component securityContext values and ingress apiServer, statsd, pgbouncer usage.
Breaking changes
  • Dropped support for all Apache Airflow versions below 2.11 in the Helm chart.
  • Default Airflow image changed from 3.1.7 to 3.1.8.
Full changelog

Significant Changes

Support for old versions of Apache Airflow <2.11 has been dropped (#61018)

Minimum supported version of Apache Airflow is now 2.11.0. If you want to deploy an
old version of Apache Airflow, please use the last released version of the chart 1.19.0.

workers specific sections have been moved to workers.celery / workers.kubernetes sections

Please update your configuration accordingly:

  • workers.command command is now deprecated in favor of workers.celery.command/workers.kubernetes.command (#60067).
  • workers.securityContexts command is now deprecated in favor of workers.celery.securityContexts/workers.kubernetes.securityContexts (#60396).
  • workers.containerLifecycleHooks command is now deprecated in favor of workers.celery.containerLifecycleHooks/workers.kubernetes.containerLifecycleHooks (#61369).
  • workers.kerberosSidecar section is now deprecated in favor of workers.celery.kerberosSidecar/workers.kubernetes.kerberosSidecar (#61881).
  • workers.kerberosInitContainer section is now deprecated in favor of workers.celery.kerberosInitContainer/workers.kubernetes.kerberosInitContainer (#60751).
  • workers.terminationGracePeriodSeconds command is now deprecated in favor of workers.celery.terminationGracePeriodSeconds/workers.kubernetes.terminationGracePeriodSeconds (#61892).
  • workers.nodeSelector command is now deprecated in favor of workers.celery.nodeSelector/workers.kubernetes.nodeSelector (#61957).
  • workers.podDisruptionBudget section is now deprecated in favor of workers.celery.podDisruptionBudget. Please update your configuration accordingly. (#61414)
  • workers.keda section is now deprecated in favor of workers.celery.keda. Please update your configuration accordingly. (#61820)
  • workers.resources section is now deprecated in favor of workers.celery.resources and workers.kubernetes.resources. Please update your configuration accordingly. (#61890)

The previous configuration options are still working, but are deprecated and will be removed in a future version.

As Git-Sync is not service-type object, the readiness probe will be removed. (#62334)

To enable feature behaviour set dags.gitSync.recommendedProbeSetting to true. Section itself will be removed in future release as to not break setups during upgrades.

As Git-Sync has dedicated liveness service, the liveness probe behaviour will be changed. To enable feature behaviour set dags.gitSync.recommendedProbeSetting to true.

Please update your configuration accordingly.

Automatic env variables removed from container_extra_envs and custom_airflow_environment (#60750)

The automatic prefix addition for Kubernetes Executor environment variables and secrets has been removed from both the container_extra_envs and custom_airflow_environment helper functions.

What changed:

Previously, when you added environment variables to component-specific configurations (e.g., .Values.scheduler.env), the chart automatically created an additional environment variable (to specified in the env section) with the AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__ prefix for Kubernetes Executor worker pods. After this change, only the variable specified in env section will be created.
Furthermore, for values specified under .Values.secret section, the AIRFLOW__KUBERNETES_SECRETS__ prefix is no longer automatically added. Secrets are now passed as-is via secretKeyRef without the prefixed copy for worker pods.

Why this change:

  • Prevent unintended exposure of sensitive data like client_secret information. Previously, due to prefix, it was recognized as internal Airflow configuration leading to unintended exposure in Airflow UI (under Admin -> Configuration), even when AIRFLOW__API__EXPOSE_CONFIG is set to non-sensitive-only.
  • Avoid unintended environment propagation to workers: component-specific env configurations are intended strictly for specific components. Previous behaviour caused these variables to be passed to worker pods, which could result in configuration conflicts and unexpected side effects.

Migration Required:

If you need to pass environment variables specifically to Kubernetes Executor worker pods, use one of the following approaches:

Option 1: Use .Values.env

.. code-block:: yaml

env:
  - name: my_var
    value: "my_value"

Environment variables specified under .Values.env are now passed as-is without the automatic prefix (same behaviour as component-specific env).

Option 2: Use .Values.config.kubernetes_environment_variables

.. code-block:: yaml

config:
  kubernetes_environment_variables:
    my_var: "my_value"

Default Airflow image is updated to 3.1.8 (#63392)

The default Airflow image that is used with the Chart is now 3.1.8, previously it was 3.1.7.

Features

  • Support Helm template expressions in podAnnotations and airflowPodAnnotations values (#63019)
  • Add minute-level log retention to clean-logs script (#61855)
  • Add LOG_MAX_SIZE environment variables to log groomer (#61559)

Improvements

  • Remove automatic KUBERNETES_ENVIRONMENT_VARIABLES and KUBERNETES_SECRETS prefixes from chart helpers (#60750)
  • Remove JWT secrets from triggerer, worker and dag-processor (#63204)
  • Add workers.celery.nodeSelector & workers.kubernetes.nodeSelector (#61957)
  • Add workers.celery.terminationGracePeriodSeconds & workers.kubernetes.terminationGracePeriodSeconds (#61892)
  • Add workers.celery.resources & workers.kubernetes.resources (#61890)
  • Add workers.celery.keda section (#61820)
  • Add workers.celery.podDisruptionBudget (#61414)
  • Add workers.celery.containerLifecycleHooks & workers.kubernetes.containerLifecycleHooks (#61369)
  • Refactor Git-Sync livenessProbe & deprecate readinessProbe & add startupProbe (#62334)
  • Warn on deprecated per-component securityContext values (#62729)
  • Add ingress deprecation warnings for apiServer, statsd, and pgbouncer (#62490)
  • Add missing support for: securityContexts and containerLifecycleHook (#60677)

Bug Fixes

  • More restrictive chart rendering logic (#63464)
  • Omit api-server spec.replicas when HPA is enabled (#63187)
  • Add workers.celery.kerberosSidecar & workers.kubernetes.kerberosSidecar sections (#61881)
  • Fix chart NOTES.txt showing deprecation warnings only without secret key (#62722)
  • Fix tpl rendering for TLS hosts in ingress templates #62358 (#62548)
  • Fix webserver.defaultUser.enabled=false not honored (#62143)

Doc only changes

  • Cleanup Helm Chart documentation (#62544)
  • Add missing deprecation warnings for workers section (#63659)

Misc

  • Drop support for all Airflow versions below 2.11 in Helm Chart (#61018)
  • Default airflow version to 3.1.8 (#63392)
  • Add *.iml to .gitignore in all distributions (#63636)
  • Upgrade important CI environment (#62792, #62610)
  • Allow to use short SPDX license identifier for selected files (#62073)
  • Fix all build-system/requires including transitive dependencies (#62570)
airflow-ctl/0.1.3 New feature
Notable features
  • Add `airflowctl auth token` command to print JWT access tokens
  • Add `--action-on-existing-key` flag to pools and connections import commands
  • Implement retry mechanism for airflowctl operations
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow-ctl/0.1.3/
📚 Docs: https://airflow.apache.org/docs/apache-airflow-ctl/0.1.3/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow-ctl/0.1.3/release_notes.html

Thanks to all the contributors who made this possible. Next time, Release notes will be available through public documentation.

Significant Changes

  • Add airflowctl auth token command to print JWT access tokens (#62843)
  • Add --action-on-existing-key to pools import and connections import (#62702)
  • Add retry mechanism to airflowctl and remove flaky integration mark (#63016)
  • airflowctl auth login: prompt for credentials interactively when none are provided (#62549)
  • feat(airflowctl): support on headless environments (#62217)

Bug Fixes

  • Fix airflowctl pools export ignoring --output table/yaml/plain (#62665)
  • Fix airflowctl connections import failure when JSON omits extra field (#62662)
  • Amend compatibility issues for airflowctl (#63388)

Improvements

  • Send limit parameter in execute_list server requests (#63048)
  • Run test coverage when airflowctl command has any change (#63216)
  • airflow-ctl: add coverage tests for console formatting output (#62627)
  • Clean up stale Python 3.9 workaround in airflow-ctl CLI config parser (#62206)
  • Expose timetable_partitioned in UI API (#62777)
3.1.8 Breaking risk
⚠ Upgrade required
  • Update security policies to grant users the `DagAccessEntity.Run` permission for backfill operations.
  • Custom auth provider implementations of `is_authorized_backfill` are deprecated and should be removed.
Breaking changes
  • Removed `is_authorized_backfill` method from `BaseAuthManager` interface; backfill checks now use `DagAccessEntity.Run` permission.
Full changelog

:package: PyPI: https://pypi.org/project/apache-airflow/3.1.8/
:books: Docs: https://airflow.apache.org/docs/apache-airflow/3.1.8/
:hammer_and_wrench: Release Notes: https://airflow.apache.org/docs/apache-airflow/3.1.8/release_notes.html
:whale: Docker Image: "docker pull apache/airflow:3.1.8"
:busstop: Constraints: https://github.com/apache/airflow/tree/constraints-3.1.8

Significant Changes

Backfill permissions are now handled via DagAccessEntity.Run (#61456)

is_authorized_backfill of the BaseAuthManager interface has been removed. Core will no longer call this method and their
provider counterpart implementation will be marked as deprecated.
Permissions for backfill operations are now checked against the DagAccessEntity.Run permission using the existing
requires_access_dag decorator. In other words, if a user has permission to run a DAG, they can perform backfill operations on it.

Please update your security policies to ensure that users who need to perform backfill operations have the appropriate DagAccessEntity.Run permissions. (Users
having the Backfill permissions without having the DagRun ones will no longer be able to perform backfill operations without any update)

Elasticsearch is now fully compatible with remote logging along (#62940)

Elasticsearch is now fully compatible with remote logging along side with apache-airflow-providers-elasticsearch>=6.5.0. Please review elasticsearch provider release notes for more information https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.5.0/changelog.html (#62121) (#62940)

Bug Fixes

  • Fix SQLite migration disable disable_sqlite_fkeys in revision 509b94a1042d (#63256) (#63272)
  • Fix: 404 queued asset events from API server logs (#62934) (#62976)
  • Fix: Always include kid in JWT header for symmetric key tokens (#62883) (#62943)
  • Fix: Scope session token in cookie to base_url (#62771) (#62851)
  • Fix: UI of Scope session token in cookie to base_url (#62771) (#62859)
  • Fix: UI tasks log missing in UP_FOR_RETRY and UP_FOR_RESCHEDULE states (#54547) (#62862)
  • Fix: Backfill permissions (#62856) (#62873)
  • Fix: Use useAssetServiceGetDagAssetQueuedEvents to get the correct number of ADRQs (#62868) (#62902)
  • Fix: Adds task instance validation for HITL (#62886) (#62909)
  • Fix: Restore task_instance_history sequence on downgrade (#62759)
  • Fix broken dag_processing.total_parse_time metric (#62128) (#62764)
  • Fix Trigger UI form rendering for null enum values (#62060) (#62767)
  • Fix timer.duration unit labels in logs (#61824) (#62757)
  • Fix XCom migration failing for NaN/Infinity float values (#62686) (#62760)
  • Fix SQL not rendered in Rendered Templates view (#60739) (#62348)
  • Fix missing DAG read permission checks on dependencies endpoint (#62046) (#62586)
  • Changed dag_bundle.signed_url_template from varchar(200) to text (#61041) (#62568)
  • Fix WASB remote logging base path handling (#58946) (#61013) (#62456)
  • Handle non-dictionary json payload during logging to avoid internal server error. (#62355) (#62367)
  • Fix grid view crash when task converted to TaskGroup (#61208) (#61279) (#62181)
  • Fix running task duration showing as null in UI (#61898) (#62136)
  • Fix deferrable sensors not respecting soft_fail on timeout (#61132) (#61421)
  • Fix task failure details being obscured by finalization errors (#62070) (#62113)
  • Add missing ti.start and ti.finish metrics in Airflow 3 (#62019) (#62110)
  • Fix DepContext mutation leak and restore reschedule-mode guard (#62089)
  • Fix scheduler heartbeat misses caused by slow reschedule dependency check (#61983) (#62068)
  • Flush in-memory OTEL metrics at process shutdown (#61808) (#61869)
  • Fix executor slots showing negative infinity (#61140) (#61768)
  • Fix recursion depth error in _redact_exception_with_context (#61776) (#61795)
  • Fix API server segfault when PYTHONASYNCIODEBUG=1 is set (#61281) (#61933)
  • Fix scheduler crash when queuing TI with null dag_version_id (#61813) (#61846)
  • Fix secrets masking in Rendered Templates for complex objects (#61394) (#61763)
  • Fix list dag versions permissions (#61675) (#61733)
  • Fix Triggerer crashing if Trigger uses builtin print function (#60258) (#61703)
  • Fix GZipMiddleware with correct comment placement (#61538) (#61566)
  • Fix middleware order to prevent chunked FastAPI responses (#61043) (#61539)
  • Fix XCom serialization for pendulum.date.Date values (#61176) (#61717)
  • Fix access_key and connection_string not being masked in logs (#61580) (#61582)
  • Fix minimatch ReDoS vulnerabilities via pnpm overrides (#62805)
  • Fix language selector state not updating on change (#61060) (#61263)
  • Make conn_type optional in task SDK Connection data model (#61728) (#61835)
  • UI: optimize grid view refresh pressure on the API (#62085) (#62135)
  • UI: Fix main content margin to align with navigation sidebar width (#61614) (#61622)
  • UI: Fix Preserve variable value formatting in edit dialog (#58757) (#62339)
  • UI: Fix missing translation keys for blocking dependencies in UI (#61314) (#61366) (#61638)
  • UI: Add error handling for pause/unpause toggle permission errors (#61389) (#61533)
  • UI: Flatten grid structure endpoint memory consumption (#61273) (#61393)
  • UI: Reduce memory usage in grid view by optimizing node data storage (#61656) (#61789)
  • UI: Fix variable table word-break when values are expanded (#62416) (#62781)
  • UI: Fix use ISO dates in Gantt chart for cross-browser consistency (#61250) (#62784)
  • UI: Fix DataTable overflow on narrow screens (#62603)
  • UI: Fix unique keys for pagination ellipses (#62352) (#62366)
  • UI: Fix elk.portConstraints for LR orientation in graph view (#62144) (#62187)
  • UI: Fix show active backfill in banner instead of first one (#61851) (#62137)
  • UI: Fix star icon visibility in Favorite filter buttons when selected (#61862)
  • UI: Fix grid view tooltip z-index issue (#61275) (#61403)
  • UI: Fix mini-map on DAG graph view not showing DAG nodes (#61511) (#61530)
  • UI: Fix pale appearance of filter buttons when selected (#60346 backport fix) (#61457)

Miscellaneous

  • Add logging to detect try number race (#62703) (#62821)
  • Override tar dependency in Simple auth manager (#62787)
  • Remove mp_start_method remnants (#61150) (#62762)
  • Expose literal and ParamsDict at SDK top level (#59782) (#62756)
  • Add on_task_instance_skipped listener hookspec (#59467) (#61863)
  • Persist table columns visibility in local storage (#61858) (#61868)
  • Add run_after alias to XComResponse for backward compatibility (#61443) (#61672)
  • UI: Add task_display_name to LightGridTaskInstanceSummary model (#61440) (#61505)
  • UI: Add multi-line text display option on Variables page (#61679) (#62779)
  • UI: Add bulk actions for connections and variables (#61570) (#62076)
  • UI: Allow selecting file path using cursor in log viewer (#61011) (#61506)

Doc Only Changes

  • Fix Liveness / Readiness / Startup probe path for Airflow 3.x (#58734) (#61411)
  • Update health check command syntax for celery worker (#58861) (#61412)
  • Translation fixes: Polish (#62031) (#62761), Catalan (#62477), Taiwanese Mandarin (#62397),
    German (#61478), Polish (#61423)
  • Remove docs mentioning old, unsupported hybrid executors (#62093) (#62096)
  • Clarify security model of Airflow (#61754) (#61770)
  • Clarify ExternalTaskSensor path in dags.rst (#61555) (#61617)
  • Clarify policy for exposing sensitive data (#59864) (#61392)
  • Clarify template context for asset-triggered DAGs in airflow-core docs (#61258) (#61282)
  • Add Keycloak token documentation to Security/API (#61228) (#61248)
airflow-ctl/0.1.2 New feature
Notable features
  • Add XCom CLI commands to airflowctl
  • Add auth list-envs command to list CLI environments and their auth status
  • Add allowed_run_types to whitelist specific dag run types
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow-ctl/0.1.2/
📚 Docs: https://airflow.apache.org/docs/apache-airflow-ctl/0.1.2/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow-ctl/0.1.2/release_notes.html

Thanks to all the contributors who made this possible. Next time, Release notes will be available through public documentation.

Significant Changes

  • Add XCom CLI commands to airflowctl (#61021)
  • Add auth list-envs command to list CLI environments and their auth status (#61426)
  • Add allowed_run_types to whitelist specific dag run types (#61833)
  • Default logical_date to now in airflowctl dagrun trigger to match UI behavior (#61047)

Bug Fixes

  • Allow listing dag runs without specifying dag_id (#61525)
  • Fix infinite password retry loop in airflowctl EncryptedKeyring initialization (#61329)
  • Fix airflowctl auth login reporting success when keyring backend is unavailable (#61296)
  • Fix airflowctl crash when incorrect keyring password is entered (#61042)
  • Strip api-url for airflowctl auth login which fails with trailing slash (#61245)
  • Fix airflow-ctl-tests files not triggering pre-commit integration tests (#61023)

Improvements

  • Print debug mode warning to stderr to avoid polluting stdout JSON output (#61302)
  • Refactor datamodel defaulting logic into dedicated method (#61236)
  • Alias run_after for XComResponse (#61443)
  • Add test for sensitive config masking in airflowctl (#60361)
helm-chart/1.19.0 Breaking risk
⚠ Upgrade required
  • Migrate ``webserver.defaultUser`` to ``createUserJob``; using the deprecated key will cause errors in future versions.
  • Update any Helm values that use deprecated ``workers.*`` keys (replicas, revisionHistoryLimit, args, livenessProbe, updateStrategy, strategy, podManagementPolicy, persistence) to the new ``workers.celery.*`` equivalents before they are removed.
Breaking changes
  • Configuration keys under ``workers`` (replicas, revisionHistoryLimit, args, livenessProbe, updateStrategy, strategy, podManagementPolicy, persistence) are deprecated and will be removed in a future version; use the corresponding ``workers.celery.*`` paths.
  • The ``webserver.defaultUser`` section is deprecated; migration to ``createUserJob`` is required for future releases.
Notable features
  • Support for multiple Celery worker sets with flexible topology via ``workers.celery.enableDefault``, queue‑aware KEDA autoscaling, and per‑set configuration overrides.
  • PodDisruptionBudgets added for Dag Processor, Triggerer, and Workers.
  • HorizontalPodAutoscaler (HPA) support introduced for the API Server.
Full changelog

Significant Changes

StatsD metrics aggregation now supports configurable TTL-enabled LRU cache to prevent memory growth in long-running daemons (#60933)

The Helm Chart now includes new configuration options for StatsD aggregation management:

  • statsd.cache.type - Enable TTL-enabled lru cache or random cache for metrics aggregation (default: lru)
  • statsd.cache.size - Maximum number of metrics to cache (default: 1000)
  • statsd.cache.ttl - Time-to-live for cached metrics in seconds (0s is TTL disabled) (default: 0s)

This feature addresses uncontrolled memory growth in StatsD daemons by automatically cleaning up stale or unused metric entries. When enabled, the cache uses both LRU (Least Recently Used) eviction and TTL (Time To Live) expiration to manage memory usage effectively.

To maintain backward compatibility, the default behaviour remains unchanged. Users experiencing memory growth issues with StatsD can enable this feature by setting statsd.cache.ttl to value higher than 0 in their Helm values.

Support for Multiple Celery Worker Sets in the Helm Chart (#58547)

This change introduces support for advanced Celery Workers topologies to Apache Airflow Helm Chart, enabling more flexible resource allocation and precise autoscaling configurations.

Flexible Worker Topologies: The new workers.celery.enableDefault flag allows users to configure a deployment consisting only of specialized worker sets defined in workers.celery.sets section.

Multi-Queue Autoscaling Support: Updates the KEDA ScaledObject generation to support comma-separated queue lists. By using the SQL IN (...) clause, we ensure that KEDA scales worker sets based on the precise aggregate workload of all their assigned queues.

Granular Configuration Overrides: This change allows for overwrite of any currently available workers configuration per worker set. For example, a user can enable KEDA globally, but explicitly disable it for a specific worker set that requires a static number of replicas.

Options to create a default user have been moved under the createUserJob section

Please update your configuration accordingly:

  • webserver.defaultUser section is now deprecated in favor of createUserJob (#59767)

The previous configuration options are still working but are deprecated and will be removed in a future version.

Note that the previous documentation described also the option apiServer.defaultUser, which was never implemented in the chart. The only supported option is now createUserJob. Using apiServer.defaultUser will raise an error.

Celery specific config options have been moved under the celery section in workers

Please update your configuration accordingly:

  • workers.replicas command is now deprecated in favor of workers.celery.replicas (#59730)
  • workers.revisionHistoryLimit command is now deprecated in favor of workers.celery.revisionHistoryLimit (#60056)
  • workers.args command is now deprecated in favor of workers.celery.args (#60163)
  • workers.livenessProbe section is now deprecated in favor of workers.celery.livenessProbe (#60186)
  • workers.updateStrategy section is now deprecated in favor of workers.celery.updateStrategy (#60351)
  • workers.strategy section is now deprecated in favor of workers.celery.strategy (#60354)
  • workers.podManagementPolicy section is now deprecated in favor of workers.celery.podManagementPolicy (#60359)
  • workers.persistence section is now deprecated in favor of workers.celery.persistence (#60238)

The previous configuration options are still working but are deprecated and will be removed in a future version.

Manual Service Account Token Volume configuration for pod-launching executors (#59156)

Added support for manual Service Account Token Volume configuration when using pod-launching executors
(CeleryExecutor, CeleryKubernetesExecutor, KubernetesExecutor, LocalKubernetesExecutor).
This implements defense-in-depth security with both ServiceAccount and Pod-level controls, providing
compatibility with security policies like Kyverno and enabling container-specific privilege assignment
following the Principle of Least Privilege.

Add imagePullSecrets option (#58094)

Add .Values.imagePullSecrets as the new mechanism for configuring registry credentials,
deprecating both .Values.registry.secretName and the automatic creation of the <RELEASE_NAME>-registry secret from .Values.registry.connection.

Default Airflow image is updated to 3.1.7 (#61447)

The default Airflow image that is used with the Chart is now 3.1.7, previously it was 3.0.2.

Default git-sync image is updated to 4.4.2 (#54085)

The default git-sync image that is used with the Chart is now 4.4.2, previously it was 4.3.0.

New Features

  • Add PodDisruptionBudget for Dag Processor (#60294)
  • Add PodDisruptionBudget for Triggerer and Workers (#59068)
  • Add HorizontalPodAutoscaler (HPA) for API Server (#52392)
  • Add support for launching jobs with KubernetesJobOperator (#52024)
  • Add CronJob to clean old records in the database (#58155)

Improvements

  • Improve dag_bundle_config_list Configuration (#60645)
  • Add workers.celery.kerberosInitContainer & workers.kubernetes.kerberosInitContainer (#60751, #60427)
  • Add workers.celery.securityContexts & workers.kubernetes.securityContexts (#60396)
  • Add workers.celery.podManagementPolicy field (#60359)
  • Add workers.celery.strategy field (#60354)
  • Add workers.celery.updateStrategy field (#60351)
  • Add workers.celery.persistence section (#60238)
  • Add workers.celery.livenessProbe section (#60186)
  • Add workers.celery.args field (#60163)
  • Add workers.celery.command & workers.kubernetes.command (#60067)
  • Allow custom volumeClaimTemplates when logs.persistence.enabled is true (#60118)
  • Add checksum for JWT secret in API server and scheduler deployments (#60111)
  • Add workers.celery.revisionHistoryLimit field (#60056)
  • Add Redis StatefulSet persistentVolumeClaimRetentionPolicy support (#59955)
  • Add workers.celery.replicas field (#59730)
  • Add custom envs to database cleanup (#59804)
  • Extend airflow_ti_running metrics by scheduled, queued and deferred (#58819)
  • Create an explicit control for createUserJob (#56057)
  • Make cleanup cronjob conditional on kubernetes executor (#58695)
  • Add database cleanup options and remove deprecated securityContext field (#58663)
  • Add ability to disable API Server (#56493)
  • Add registry.secretNames and registry.connections options (#58094)
  • Allow custom labels in StatsD, redis and Dag Processor (#55832)
  • Allow setting restartPolicy for batch jobs in chart (#54354)
  • Add readiness and liveliness support for git sync relay sidecars (#50218)
  • Allow overriding schedulerName on worker/tasks pods (#53983)
  • Allow additional PodDisruptionBudget config properties (#58864)
  • Add EdgeExecutor to KEDA query (#55560)
  • Allow revisionHistoryLimit to be set to 0 (#60340)
  • Allow optional subPath for logs volume mount (#52350)
  • Move triggerer from pod-log-reader-role to pod-launcher-role (#56872)

Bug Fixes

  • Remove kedaNetworkPolicySelector from helpers (#61564)
  • Use the bitnamilegacy/postgresql image (#61156)
  • Fix Compatibility of Celery Worker Sets with Workers Separation (#60420)
  • Fix database cleanup cronjob ImagePullSecrets (#58626)
  • Remove workers.celery breaking change (#61049)
  • Fix missing templating in API Server extraInitContainers (#60812)
  • Fix securityContext.containers/ingress.apiServer in values.schema.json (#60575)
  • Remove unused containerLifecycleHooks field (#60239)
  • Remove unneeded logic in api-server (#60147)
  • Remove defaultUser from API Server in values.schema.json (#59762)
  • Isolate defaultUser handling in createUserJob (#59767)
  • Fix rendering condition of git_sync_ssh_key_volume (#59418)
  • Add watch for events to the Pod launcher role (#59080)
  • Ensure that git-sync actually runs when dags.gitSync.enabled=true and dags.persistence.enabled=true (#59123)
  • Don't add labels to non-existent configuration options (#59213)
  • Add log volume to init container for scheduler, triggerer and worker (#56418)
  • Correctly derive celery sync_parallelism from scheduler CPU limits (#58733)
  • Fix ingress notes (#59122)
  • Fix Liveness / Readiness / Startup probe path for Airflow 3.x (#58734)
  • Fix flower network policy condition when multiple executors (#58635)
  • Missing SCC Role bindings for redis and api-server (#57985)
  • Ensure graceful Redis shutdown(#58432)
  • Start Redis directly, not via shell (#58790)
  • Add missing airflow.fullname on kubernetes objects (#52953)
  • StatsD deployment volume mount without subpath for live reloading (#54986)
  • Fix KEDA query for Kubernetes Executor (#55559)
  • Add API Server config in k8s pod template (#53533)
  • Fix helm schema validation for executor value (#54682)
  • Correct watch verb quoting in Airflow Job Launcher Role (#53822)
  • Trim non-alphanumeric characters from the executor label (#53534)
  • Fix KEDA Query to Use executor Field Instead of queue for Multiple Executors (#52840)

Doc only changes

  • Document how to run the API server behind a reverse proxy (#61095)
  • Clarify ingress settings for Airflow 2 vs 3 in values.yaml (#60434)
  • Add database cleanup docs to Helm productions docs (#58707)
  • KEDA best practices + better documentation (#58246)
  • Update chart info about built-in secrets and environment variables (#58317)
  • Fix typo in PgBouncer section of the Production Guide (#56754)
  • Update webserver secret note in NOTES.txt and Production Guide (#55106)
  • Make term Dag consistent in docs v2 (#55099)
  • Add API Server to container resources docs (#54698)
  • Fix YAML block scalar when providing SSH key for git-sync (#56716)
3.1.7 Bug fix

Fixed JWT token generation when issuer/audience config is unset.

Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow/3.1.7/
📚 Docs: https://airflow.apache.org/docs/apache-airflow/3.1.7/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow/3.1.7/release_notes.html
🐳 Docker Image: "docker pull apache/airflow:3.1.7"
🚏 Constraints: https://github.com/apache/airflow/tree/constraints-3.1.7

Significant Changes

No significant changes.

Bug Fixes

  • Fix JWT token generation with unset issuer/audience config (#61331)
  • Fix callback files losing priority during queue resort (#61232) (#61243)
  • Fix Dag callback for versioned bundles in the processor (#60734) (#61230)
  • Add 404 handling for non-existent Dag (#61131) (#61225)
  • Add guardrail to handle Dag deserialization errors in scheduler (#61162) (#61210)
  • Fix asset scheduling for stale Dags (#59337) (#60022) (#61106)
  • Fix unnecessary Dag version churn when Dag file paths change (#60799)
  • Fix missing warning when Bundle path may not be accessible to impersonated user (#60278)
  • Fix TriggerDagRunOperator deferring when wait_for_completion=False (#60052)
  • Fix NoneType error when updating serialized Dag (#56422)
  • Fix Pool API slots validation (#61071) (#61114)
  • Fix DagBag parsing by adding bundle_path temporarily to sys.path (#55894) (#61053)
  • Fix API to respect maximum page limit (#60989) (#61073)
  • Prevent Triggerer from crashing when a trigger event isn't serializable (#60152) (#60981)
  • Fix permissions on get_event_logs endpoint (#60936) (#60958)
  • Fix Dag access control for dag_id in query param (#60935) (#60959)
  • Fix root logger to use log_level instead of hardcoded INFO level (#60784) (#60970)
  • Fix Dag processor OOM by Avoid loading all TaskInstances when checking DagVersion in write_dag (#60937) (#60962)
  • Fix worker startup Dag load failures by rescheduling tasks instead of exiting (#59604) (#60926)
  • Fix permissions check in import error APIs (#60801) (#60884)
  • Fix refresh-token invalidation by logging out the user (#60781) (#60881)
  • Fix connection test API to restore masked password/extra from existing connections (#59643) (#60873)
  • Fix Dag processor overhead by applying gc.freeze (#60505) (#60845)
  • Fix Dag processor crashing due to MySQL deadlock errors (#60166) (#60418)
  • Ensure unique run_id across manually triggered Dags with schedules (#59477) (#60468)
  • UI: Avoid gantt annotation error during resize (#60877)
  • UI: Fix react apps plugins router (#61206)
  • UI: Reset pagination on search in all pages (#61169)
  • UI: Explicitly set UI table ordering (#60609) (#61216)
  • UI: Plugins pagination fix #61055 (#61059) (#61129)
  • UI: Fix ui get dags permission endpoint for user without Dag run permissions (#60979) (#60988)
  • UI: Convert Tasks Table from card to table mode (#60830) (#60874)
  • UI: Fix slow log scrolling for large task logs (#60806) (#60875)
  • UI: Grey out trigger button on API 403 (#60648) (#60777)
  • UI: Remove API error from disabling submit (#60473) (#60658)
  • UI: Added toasters for permission denied (#57966) (#58016) (#60646)
  • UI: Move row count and display toggle into DataTable (#57680) (#60639)
  • UI: Fix/backfill permission error handling (#60582) (#60587)
  • UI: Improve Dags Filter UI (#60346) (#60547)
  • UI: Update PoolBar to separate Scheduled and Deferred slots (#59270) (#60538)
  • UI: Correct the access for the externalLogUrl (#60412) (#60479)
  • UI: Fix gantt chart styling (#60347) (#60457)
  • UI: Reset pagination on DagList search (#60326) (#60336)
  • UI: Move dags list filters to buttongroups (#60298) (#60337)
  • UI: Fix table filters resetting when deleting a Dag (#60279) (#60287)
  • UI: Fix sidebar visibility issue when main content exceeds viewport height (#59660) (#60286)
  • UI: Add virtualization to grid view (#60241) (#60285)

Miscellaneous

  • UI: Upgrade react-dom-router in Airflow UI (#60316) (#60456)
  • Use bulk DELETE for XComModel.clear() instead of loading records (#60955)
  • Refactor Dag file queuing and fix redundant processing (#60124)
  • Optimized Dag processing queue order on bundle refresh (#60003)
  • Remove unused method is_default_pool in Pool model (#61084) (#61128)
  • Translation fixes: Taiwaness Mandarin (#61126), Catalan (#61093), German (#61097), Polish (#61099),
    Arabic (#60635 #60782, (#60635) (#60782)), Spanish (#60775 #60785, (#60775) (#60785)),
    Hebrew (#60633 #60686, (#60633) (#60686))

Doc Only Changes

  • Fix minor display issue with migration to airflow 3 docs (#60749)
  • Fix airflow.utils.context.Context import path in Airflow 3 migration doc (#59937)
  • Add missing links to airflow.sdk classes and functions in public interface docs (#61005) (#61012)
  • Clarify BaseSensorOperator parameters in Sensors guide (#60275)
  • Fix docstring for RuntimeTaskInstance.xcom_pull (#60220) (#60252)
  • Fix broken syntax highlighting in AIR rules note section (#59188)
airflow-ctl/0.1.1 Breaking risk
Breaking changes
  • Removed deprecated `export` functionality from `airflowctl`
  • Increased minimum supported `prek` version to 0.2.0
Notable features
  • Added `team_name` argument to connection commands
  • Added `team_id` argument to variable commands
  • Display active DAG run count with auto-refresh in the `dags` command header
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow-ctl/0.1.1/
📚 Docs: https://airflow.apache.org/docs/apache-airflow-ctl/0.1.1/
🛠 Release Notes: https://github.com/apache/airflow/blob/airflow-ctl/0.1.1/airflow-ctl/RELEASE_NOTES.rst

Thanks to all the contributors who made this possible. Next time, Release notes will be available through public documentation.

Significant Changes

  • Make pause/unpause commands positional for improved CLI consistency (#59936)
    Provides separate airflowctl dags pause/unpause dag_id
  • Remove deprecated export functionality from airflowctl (#59850)
    airflowctl won't export from
  • Add team_name to connection commands (#59336)
    Team name feature added to connections command
  • Add team_id to variable commands (#57102)
  • Add pre-commit checks for airflowctl test coverage (#58856)
    Provided more coverage and further checks on integration tests to release with more confidence.
  • Display active DAG run count in header with auto-refresh support (#58332)
    active_runs_count has been added to the dags command.

Bug Fixes

  • Simplify airflowctl exception handling in safe_call_command (#59808)
  • Fix backfill default behavior for run_on_latest_version (#59304)
  • Update BulkDeleteAction to use generic typing (#59207)
  • Bump minimum supported prek version to 0.2.0 (#58952)
  • Fix RST formatting to ensure blank lines before bullet lists (#58760)
  • Update Python compatibility requirements and airflowctl documentation (#58653)
  • Consistently exclude unsupported Python 3.14 (#58657)
  • Improve cross-distribution dependency management (#58430)
  • Synchronize documentation between official and convenience source installs (#58379)
  • Add retry multiplier support (#56866)
  • Fix documentation issues for installing from source distributions (#58366)
  • Update pyproject.toml files to support pytest>=9.0.0 TOML syntax (#58182)
3.1.6 Breaking risk
Notable features
  • `is_authorized_hitl_task()` method added to auth managers for HITL task approval checks
  • `proxy` and `proxies` included in `DEFAULT_SENSITIVE_FIELDS` to mask proxy configuration secrets
Full changelog

📦 PyPI: https://pypi.org/project/apache-airflow/3.1.6/
📚 Docs: https://airflow.apache.org/docs/apache-airflow/3.1.6/
🛠 Release Notes: https://airflow.apache.org/docs/apache-airflow/3.1.6/release_notes.html
🐳 Docker Image: "docker pull apache/airflow:3.1.6"
🚏 Constraints: https://github.com/apache/airflow/tree/constraints-3.1.6

Significant Changes

is_authorized_hitl_task() method now available in auth managers(#59399).

This method is now available in auth managers to check whether a user is authorized to approve a HITL task

proxy and proxies added to DEFAULT_SENSITIVE_FIELDS (#59688)

proxy and proxies have been added to DEFAULT_SENSITIVE_FIELDS in secrets_masker to treat proxy configurations as sensitive by default

Bug Fixes

  • Protect against hanging thread in aiosqlite 0.22+ (#60217) (#60245)
  • Fix log task instance sqlalchemy join query (#59973) (#60222)
  • Fix invalid uri created when extras contains non string elements (#59339) (#60219)
  • Fix operator template fields via callable serialization that causes unstable DAG serialization (#60065) (#60221)
  • Fix real-time extra links updates for TriggerDagRunOperator (#59507) (#60225)
  • Fix signal handling in triggerer job runner (#60190) (#60214)
  • Added state validation to delete dag run endpoint (#60195) (#60207)
  • Fix text overflow issue (#60080)
  • UI: Add toggle functionality to Dags state filters (#59089)
  • Fix deprecated_options entry for dag_file_processor_timeout (#59181) (#60162)
  • Fix ApprovalOperator with SimpleAuthManager when all_admins=True (#59399) (#60116)
  • Record missing ti_failure metrics for tasks (#59731) (#59964)
  • Fix missing TaskInstanceHistory on scheduler TI resets (#59639) (#59752)
  • Add proxy and proxies as sensitive fields in DEFAULT_SENSITIVE_FIELDS (#59688) (#59792)
  • Fix compat deprecation handling for [webserver] base_url (#59659) (#59781)
  • Fix Execution API refresh token (#58782) (#59713)
  • Fix eager-loading DagRun asset relationships before creating DagRunContext (#59714) (#59732)
  • Redact secrets in rendered templates properly when truncating it (#59566) (#59704)
  • Add Content-Type to request headers in Task SDK calls when missing (#59676) (#59687)
  • UI: Fix Expand+Collapse Translation Key (#59672) (#59674)
  • Fix server context for connections (#59624) (#59652)
  • Fix clear task instance dialog tasks states (#59363) (#59580)
  • Add log record when listening dag is partitioned but run has no key (#59375) (#59582)
  • Fix Dag Processor logging crash (#59317) (#59581)
  • Flush session before processing Event Buffer in dag test (#59314) (#59559)
  • Add task group ID filtering support to task instance query (#58092) (#59511)
  • Fix message of _read_from_logs_server when status_code is 403 (#59489) (#59504)
  • Fix import errors not cleared for files without Dags (#58242) (#59500)
  • Fix backfill run_on_latest_version defaulting to False instead of True (#59304) (#59328)
  • Add toaster notifications for Connection Test (#59354) (#59368)
  • Fix .airflowignore negation not working in subfolders (#58740) (#59305)
  • Fix XCom key handling when keys contain special characters like slash (#58344) (#59311)
  • Fix an odd import of pendulum from sqlalchemy_utils instead of elsewhere. (#59258) (#59265)
  • Fix links for DurationChart (#59095) (#59237)
  • Fix misleading error message when GitHook creation fails (#59236)
  • Show asset extra in asset list (#59195) (#59201)
  • Prevent dag processor crash on encountering excel files in the Dag directory (#59069) (#59170)
  • Fix DagRun.queued_at not updating when clearing (#59066) (#59177)
  • Fix Rendered Templates not showing dictionary items (#58071) (#59176)
  • UI: Change task log source display to hidden by default (#58749) (#59045)
  • Fix button to go back from FAB iframe (#58997) (#59007)
  • Fix task instance and run tooltips in Grid view (#58359) (#59013)

Miscellaneous

  • Don't depend upon FastAPI inside Task-SDK client (#59250) (#59257)
  • Align the term Dag in all translations (#59155)

Doc Only Changes

  • Bump Sphinx Airflow theme to 0.3.0 (#59538)
  • Translations updates [French: (#60157) (#60167), German: (#59673), PL: (#59675) (#59251) (#59256), Japanese: (#59557),(#59313),
    Taiwanese Mandarin (#59513) (#59515), Hebrew: (#59133) (#59255), Ca: (#59216) (#60199), TR: (#59169) (#60191)]
  • Update webserver probe health check doc (#59942) (#59982)
  • Update API auth. instructions in Docker running docs (#59830) (#59832)
  • Improve CLI date argument help text documentation (#59797) (#59810)
  • Add fast client-side search to Airflow documentation (#59658)
  • Fix broken permalink icon (#58763)
  • Add Refresh Token logic to auth manager docs (#54196) (#59482)
  • Update json to JSON for consistency in translations (#59323) (#59333)
  • Fix outdated dependency documentation (#58970) (#59219)
  • Add UI/API performance tips (#59004) (#59052)
  • Provide a clear naming and description for the attribute caching get_template_context (#59023) (#59036)
  • Update the documentation for the LocalExecutor (#58990) (#59022)

Beta — feedback welcome: [email protected]