Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix Internal Server Error in API server due to KeycloakPostError when refreshing user in Keycloak provider#59361

Merged
vincbeck merged 3 commits intoapache:mainfrom
dabla:fix/keycloak-provider-invalid-token-on-user-refresh
Dec 12, 2025
Merged

Fix Internal Server Error in API server due to KeycloakPostError when refreshing user in Keycloak provider#59361
vincbeck merged 3 commits intoapache:mainfrom
dabla:fix/keycloak-provider-invalid-token-on-user-refresh

Conversation

Copy link
Contributor

dabla commented Dec 12, 2025

This PR fixes issue #59359 which fixes an Internal Server Error in the Airflow API server due to a KeycloakPostError when refreshing user in Keycloak provider.

This is because the Airflow API server has a cookie with an expired _token. That token never expires due to an expiration set to Session, thus the cookie is never invalided which at a certain time leads to an invalid token send to Keycloak.

This leads to following exception in API server which makes the API server respond with a HTTP 500 Internal Server Error:

... ) keycloak.exceptions.KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'">INFO: 172.31.52.95:0 - "GET /favicon.ico HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
+ Exception Group Traceback (most recent call last):
| File "/usr/local/lib/python3.13/site-packages/starlette/_utils.py ", line 79, in collapse_excgroups
| yield
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/base.py", line 183, in __call__
| async with anyio.create_task_group() as task_group:
| ~~~~~~~~~~~~~~~~~~~~~~~^^
| File "/usr/local/lib/python3.13/site-packages/anyio/_backends/_as yncio.py", line 783, in __aexit__
| raise BaseExceptionGroup(
| "unhandled errors in a TaskGroup", self._exceptions
| ) from None
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/h ttp/httptools_impl.py", line 409, in run_asgi
| result = await app( # type: ignore[func-returns-value]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| self.scope, self.receive, self.send
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| )
| ^
| File "/usr/local/lib/python3.13/site-packages/uvicorn/middleware/ proxy_headers.py", line 60, in __call__
| return await self.app(scope, receive, send)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.13/site-packages/fastapi/application s.py", line 1082, in __call__
| await super().__call__(scope, receive, send)
| File "/usr/local/lib/python3.13/site-packages/starlette/applicati ons.py", line 113, in __call__
| await self.middleware_stack(scope, receive, send)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/errors.py", line 186, in __call__
| raise exc
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/errors.py", line 164, in __call__
| await self.app(scope, receive, _send)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 29, in __call__
| await responder(scope, receive, send)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 130, in __call__
| await super().__call__(scope, receive, send)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 46, in __call__
| await self.app(scope, receive, self.send_with_compression)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/cors.py", line 85, in __call__
| await self.app(scope, receive, send)
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/base.py", line 182, in __call__
| with recv_stream, send_stream, collapse_excgroups():
| ~~~~~~~~~~~~~~~~~~^^
| File "/usr/lib64/python3.13/contextlib.py", line 162, in __exit__
| self.gen.throw(value)
| ~~~~~~~~~~~~~~^^^^^^^
| File "/usr/local/lib/python3.13/site-packages/starlette/_utils.py ", line 85, in collapse_excgroups
| raise exc
| File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/base.py", line 184, in __call__
| response = await self.dispatch_func(request, call_next)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.13/site-packages/airflow/api_fastapi /auth/middlewares/refresh_token.py", line 45, in dispatch
| new_user = await self._refresh_user(current_token)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.13/site-packages/airflow/api_fastapi /auth/middlewares/refresh_token.py", line 68, in _refresh_user
| return get_auth_manager().refresh_user(user=user)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
| File "/usr/local/lib/python3.13/site-packages/airflow/providers/k eycloak/auth_manager/keycloak_auth_manager.py", line 121, in refresh_user
| tokens = client.refresh_token(user.refresh_token)
| File "/usr/local/lib/python3.13/site-packages/keycloak/keycloak_o penid.py", line 410, in refresh_token
| return raise_error_from_response(data_raw, KeycloakPostError)
| File "/usr/local/lib/python3.13/site-packages/keycloak/exceptions .py", line 195, in raise_error_from_response
| raise error(
| ...<3 lines>...
| )
| keycloak.exceptions.KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'
+------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/h ttp/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.scope, self.receive, self.send
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/local/lib/python3.13/site-packages/uvicorn/middleware/ proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/fastapi/application s.py", line 1082, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.13/site-packages/starlette/applicati ons.py", line 113, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/errors.py", line 186, in __call__
raise exc
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 29, in __call__
await responder(scope, receive, send)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 130, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/gzip.py", line 46, in __call__
await self.app(scope, receive, self.send_with_compression)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/cors.py", line 85, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/base.py", line 182, in __call__
with recv_stream, send_stream, collapse_excgroups():
~~~~~~~~~~~~~~~~~~^^
File "/usr/lib64/python3.13/contextlib.py", line 162, in __exit__
self.gen.throw(value)
~~~~~~~~~~~~~~^^^^^^^
File "/usr/local/lib/python3.13/site-packages/starlette/_utils.py ", line 85, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.13/site-packages/starlette/middlewar e/base.py", line 184, in __call__
response = await self.dispatch_func(request, call_next)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/airflow/api_fastapi /auth/middlewares/refresh_token.py", line 45, in dispatch
new_user = await self._refresh_user(current_token)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/airflow/api_fastapi /auth/middlewares/refresh_token.py", line 68, in _refresh_user
return get_auth_manager().refresh_user(user=user)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/airflow/providers/k eycloak/auth_manager/keycloak_auth_manager.py", line 121, in refresh_user
tokens = client.refresh_token(user.refresh_token)
File "/usr/local/lib/python3.13/site-packages/keycloak/keycloak_o penid.py", line 410, in refresh_token
return raise_error_from_response(data_raw, KeycloakPostError)
File "/usr/local/lib/python3.13/site-packages/keycloak/exceptions .py", line 195, in raise_error_from_response
raise error(
...<3 lines>...
)
keycloak.exceptions.KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in airflow-core/newsfragments.

dabla requested review from bugraoz93 and vincbeck as code owners December 12, 2025 12:38
vincbeck approved these changes Dec 12, 2025
Copy link
Contributor

vincbeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

dabla reacted with thumbs up emoji
vincbeck merged commit 626af79 into apache:main Dec 12, 2025
82 checks passed
TempestShaw pushed a commit to TempestShaw/airflow that referenced this pull request Dec 24, 2025
... refreshing user in Keycloak provider (apache#59361)

* fix: fix KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'

* refactor: Reformatted test_refresh_user_expired_with_invalid_token
shahar1 mentioned this pull request Dec 30, 2025
54 tasks
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
... refreshing user in Keycloak provider (apache#59361)

* fix: fix KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'

* refactor: Reformatted test_refresh_user_expired_with_invalid_token
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
... refreshing user in Keycloak provider (apache#59361)

* fix: fix KeycloakPostError: 400: b'{"error":"invalid_grant","error_description":"Token is not active"}'

* refactor: Reformatted test_refresh_user_expired_with_invalid_token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

vincbeck vincbeck approved these changes

bugraoz93 Awaiting requested review from bugraoz93 bugraoz93 is a code owner

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants