apache / apache/airflow

Upgrading to 3.1.3 yields 401 Unauthorized error

Open
#59,279 3 comments 0 reactions 0 assignees View on GitHub
affected_version:3.1 area:API area:core area:helm-chart kind:bug
Dominant language
Python
Stars
46.9k
Forks
17.8k
Avg merge
2d 7h
Merged PRs (30d)
484

Description

### Apache Airflow version

3.1.3

### If "Other Airflow 2/3 version" selected, which one?

_No response_

### What happened?

I tried to upgrade my airflow helm chart from version 3.0.2 to version 3.1.3.
I started with a fresh database and namespace, but when I try to access airflow at http://airflow.staging.mydomain.cloud I get redirected to http://airflow.staging.mydomain.cloud/auth/login/?next=http://airflow.staging.mydomain.cloud/ and it shows `Internal Server Error`.

Inspecting the api-server logs I found this:
```
INFO: 10.42.5.9:48748 - "GET /ui/config HTTP/1.1" 401 Unauthorized

INFO: 10.42.5.9:48754 - "GET /static/i18n/locales/en/common.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48748 - "GET /static/i18n/locales/en/dashboard.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48768 - "GET /static/i18n/locales/en/dags.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48786 - "GET /static/i18n/locales/en/assets.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48774 - "GET /static/i18n/locales/en/components.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48748 - "GET /static/i18n/locales/en/browse.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48754 - "GET /static/i18n/locales/en/admin.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48792 - "GET /static/i18n/locales/en/hitl.json HTTP/1.1" 304 Not Modified

INFO: 10.42.5.9:48792 - "GET /api/v2/auth/login?next=http%3A%2F%2Fairflow.staging.translated.cloud%2F HTTP/1.1" 307 Temporary Redirect

2025-12-10T15:27:14.185556Z [error ] Exception in callback .task_done at 0x74592c24fb00>

handle: .task_done> [asyncio] loc=runners.py:118

Traceback (most recent call last):

File "uvloop/cbhandles.pyx", line 63, in uvloop.loop.Handle._run

File "/home/airflow/.local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 820, in task_done

self._on_completed_fut.set_result(None)

asyncio.exceptions.InvalidStateError: invalid state

2025-12-10T15:27:14.187211Z [error ] Exception in callback .task_done at 0x74592c24eb60>

handle: .task_done> [asyncio] loc=runners.py:118

Traceback (most recent call last):

File "uvloop/cbhandles.pyx", line 63, in uvloop.loop.Handle._run

File "/home/airflow/.local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 825, in task_done

exc = _task.exception()

^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 144, in coro

await self.app(scope, receive_or_disconnect, send_no_error)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 63, in __call__

await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app

await app(scope, receive, sender)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 716, in __call__

await self.middleware_stack(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 736, in app

await route.handle(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 462, in handle

await self.app(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/fastapi/applications.py", line 1082, in __call__

await super().__call__(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/applications.py", line 113, in __call__

await self.middleware_stack(scope, receive, send)

File "/opt/datadog/apm/library/python/ddtrace_pkgs/site-packages-ddtrace-py3.11-manylinux2014/ddtrace/contrib/internal/asgi/middleware.py", line 456, in __call__

return await self.app(scope, wrapped_recv, wrapped_send)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__

await self.app(scope, receive, _send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 63, in __call__

await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app

await app(scope, receive, sender)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 716, in __call__

await self.middleware_stack(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 736, in app

await route.handle(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/routing.py", line 462, in handle

await self.app(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/wsgi.py", line 81, in __call__

await responder(receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/wsgi.py", line 101, in __call__

message = await receive()

^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 117, in receive_or_disconnect

async with anyio.create_task_group() as task_group:

File "/home/airflow/.local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 755, in __aexit__

await self._on_completed_fut

asyncio.exceptions.CancelledError: Cancelled via cancel scope 74592c5d9cd0 by .call_next..coro() running at /home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py:144> cb=[TaskGroup._spawn..task_done() at /home/airflow/.local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py:805]>

INFO: 10.42.5.9:48792 - "GET /auth/login/?next=http://airflow.staging.translated.cloud/ HTTP/1.1" 500 Internal Server Error

ERROR: Exception in ASGI application

+ Exception Group Traceback (most recent call last):

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/_utils.py", line 79, in collapse_excgroups

| yield

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 183, in __call__

| async with anyio.create_task_group() as task_group:

| File "/home/airflow/.local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 783, in __aexit__

| raise BaseExceptionGroup(

| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)

+-+---------------- 1 ----------------

| Traceback (most recent call last):

| File "/home/airflow/.local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi

| result = await app( # type: ignore[func-returns-value]

| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| File "/home/airflow/.local/lib/python3.11/site-packages/fastapi/applications.py", line 1082, in __call__

| await super().__call__(scope, receive, send)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/applications.py", line 113, in __call__

| await self.middleware_stack(scope, receive, send)

| File "/opt/datadog/apm/library/python/ddtrace_pkgs/site-packages-ddtrace-py3.11-manylinux2014/ddtrace/contrib/internal/asgi/middleware.py", line 456, in __call__

| return await self.app(scope, wrapped_recv, wrapped_send)

| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__

| raise exc

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__

| await self.app(scope, receive, _send)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 29, in __call__

| await responder(scope, receive, send)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 130, in __call__

| await super().__call__(scope, receive, send)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 46, in __call__

| await self.app(scope, receive, self.send_with_compression)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in __call__

| await self.app(scope, receive, send)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 182, in __call__

| with recv_stream, send_stream, collapse_excgroups():

| File "/usr/python/lib/python3.11/contextlib.py", line 158, in __exit__

| self.gen.throw(typ, value, traceback)

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/_utils.py", line 85, in collapse_excgroups

| raise exc

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 184, in __call__

| response = await self.dispatch_func(request, call_next)

| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| File "/home/airflow/.local/lib/python3.11/site-packages/airflow/api_fastapi/auth/middlewares/refresh_token.py", line 49, in dispatch

| response = await call_next(request)

| ^^^^^^^^^^^^^^^^^^^^^^^^

| File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 160, in call_next

| raise RuntimeError("No response returned.")

| RuntimeError: No response returned.

+------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/home/airflow/.local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi

result = await app( # type: ignore[func-returns-value]

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/fastapi/applications.py", line 1082, in __call__

await super().__call__(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/applications.py", line 113, in __call__

await self.middleware_stack(scope, receive, send)

File "/opt/datadog/apm/library/python/ddtrace_pkgs/site-packages-ddtrace-py3.11-manylinux2014/ddtrace/contrib/internal/asgi/middleware.py", line 456, in __call__

return await self.app(scope, wrapped_recv, wrapped_send)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__

raise exc

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__

await self.app(scope, receive, _send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 29, in __call__

await responder(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 130, in __call__

await super().__call__(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 46, in __call__

await self.app(scope, receive, self.send_with_compression)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in __call__

await self.app(scope, receive, send)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 182, in __call__

with recv_stream, send_stream, collapse_excgroups():

File "/usr/python/lib/python3.11/contextlib.py", line 158, in __exit__

self.gen.throw(typ, value, traceback)

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/_utils.py", line 85, in collapse_excgroups

raise exc

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 184, in __call__

response = await self.dispatch_func(request, call_next)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/airflow/api_fastapi/auth/middlewares/refresh_token.py", line 49, in dispatch

response = await call_next(request)

^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/airflow/.local/lib/python3.11/site-packages/starlette/middleware/base.py", line 160, in call_next

raise RuntimeError("No response returned.")

RuntimeError: No response returned.
```

### What you think should happen instead?

I should be able to access the login page

### How to reproduce

Custom docker image:
```
FROM apache/airflow:3.1.3-python3.11

USER root

RUN apt-get update && \
apt-get install -y git g++ php php-cli php-common && \
apt-get clean && rm -rf /var/lib/apt/lists/*

USER airflow
```

Helm values:
```
images:
airflow:
repository: ${IMAGE_NAME}
tag: ${VERSION}
pullPolicy: Always

ingress:
apiServer:
enabled: true
annotations:
projectcontour.io/response-timeout: "120s"
hosts:
- name: "airflow.staging.mydomain.cloud"
ingressClassName: "contour"

env:
- name: "AIRFLOW__API__AUTH_BACKEND"
value: "airflow.api.auth.backend.basic_auth"
- name: "AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION"
value: "True"
- name: "AIRFLOW__CORE__LOAD_EXAMPLES"
value: "False"
- name: AIRFLOW__CORE__EXECUTE_TASKS_NEW_PYTHON_INTERPRETER
value: "True"
- name: AIRFLOW__LOGGING__REMOTE_LOGGING
value: "True"
- name: AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID
value: "LoggingS3Connection"
- name: AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER
value: "s3://logs-archive-product-team/Airflow"
- name: AIRFLOW__LOGGING__ENCRYPT_S3_LOGS
value: "False"
- name: AIRFLOW__CORE__ENABLE_XCOM_PICKLING
value: "True"
- name: AIRFLOW__SMTP__SMTP_HOST
value: "smtp.gmail.com"
- name: AIRFLOW__SMTP__SMTP_PORT
value: "587"
- name: AIRFLOW__SMTP__SMTP_SSL
value: "False"
- name: AIRFLOW__SMTP__SMTP_STARTTLS
value: "True"
- name: AIRFLOW__SMTP__SMTP_USER
value: "robot@mydomain.net"
- name: "CM_API_URL"
value: "https://cm-api.mydomain.cloud/api"

secret:
- envName: "GIT_TOKEN"
secretName: "airflow-git-token"
secretKey: "GIT_TOKEN"

data:
metadataSecretName: "airflow-pgbouncer-connection"

apiSecretKey: ${API_SECRET_KEY}
jwtSecret: ${JWT_SECRET}
fernetKey: ${FERNET_KEY}
webserverSecretKey: ${WEBSERVER_SECRET_KEY}

workers:
replicas: 1

registry:
secretName: regcred

postgresql:
enabled: false

pgbouncer:
enabled: true
configSecretName: airflow-pgbouncer-config
metricsExporterSidecar:
statsSecretName: airflow-pgbouncer-stats

dags:
gitSync:
enabled: true
repo: git@github.com:mydomain/airflow-dags.git
branch: develop
ref: develop
depth: 1
subPath: "dags"
sshKeySecret: airflow-ssh-secret
```

Deployment script:
```
export PGBOUNCER_INI_BASE64=$(envsubst < k8s/pgbouncer/pgbouncer.ini | base64 -w 0)
export PGBOUNCER_USERS_BASE64=$(envsubst < k8s/pgbouncer/users.txt | base64 -w 0)
envsubst airflow-pgbouncer-connection.yaml
envsubst airflow-pgbouncer-stats.yaml
envsubst airflow-pgbouncer-config.yaml
envsubst airflow-aws-secrets.yaml
envsubst airflow-connections-secrets.yaml
envsubst airflow-git-secrets.yaml
envsubst airflow-git-token.yaml

echo Installing secrets
ssh -p 2222 docker-deploy@${SWARM_HOST} 'cat - | kubectl apply -f -' airflow-values.yml

echo Airflow helm repo adding
ssh -p 2222 docker-deploy@${SWARM_HOST} 'helm repo add apache-airflow https://airflow.apache.org'
ssh -p 2222 docker-deploy@${SWARM_HOST} 'helm repo update'

echo Airflow Helm installing

ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=10 -p 2222 docker-deploy@${SWARM_HOST} "cat - | helm upgrade --install airflow apache-airflow/airflow --namespace airflow-$ENV -f -"

Contributor guide

Open the contributing guide

Research direction

Reproduce the upgrade from Helm chart 3.0.2 to 3.1.3 with a fresh database and namespace, then inspect the /ui/config and /api/v2/auth/login requests. Start with airflow/api_fastapi/auth/middlewares/refresh_token.py and the reported 401, 500, and anyio errors. Done means the login flow completes without the Internal Server Error after the upgrade.

Written by the indexing model from the issue text.

Assessment

Tech stack
helm, kubernetes, python
Domain
authentication, backend, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.