Skip to content

Commit 4fa0d01

Browse files
authored
Explicitly set the JWTGenerator private_key field to None for service logs retrieval (#54442)
In a recent change, the private_key parameter is left empty when instantiating the JWTGenerator used to authenticate log serving requests for in-progress tasks. Such requests use the shared secret_key instead. However, leaving private_key unset means that it is automatically populated through the attrs field factory and this leads to a failure in the post init which asserts mutual exclusivity of secret_key and private_key. The result is stack traces in the API Server logs like the following when retrieving "live" logs: ``` [2025-08-12T19:33:59.403+0000] {file_task_handler.py:907} ERROR - Could not read served logs Traceback (most recent call last): File "/usr/local/lib/python3.12/site-packages/airflow/utils/log/file_task_handler.py", line 878, in _read_from_logs_server response = _fetch_logs_from_service(url, rel_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/airflow/utils/log/file_task_handler.py", line 173, in _fetch_logs_from_service generator = JWTGenerator( ^^^^^^^^^^^^^ File "<attrs generated methods airflow.api_fastapi.auth.tokens.JWTGenerator>", line 34, in __init__ self.__attrs_post_init__() File "/usr/local/lib/python3.12/site-packages/airflow/api_fastapi/auth/tokens.py", line 417, in __attrs_post_init__ raise ValueError("Exactly one of private_key and secret_key must be specified") ValueError: Exactly one of private_key and secret_key must be specified ``` The fix is to add back the explicit `private_key=None`, for which we have to add a mypy type ignore comment as it does not seem to understand that `None` is allowed for `AllowedPrivateKeys | None`.
1 parent a51ef23 commit 4fa0d01

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

airflow-core/src/airflow/utils/log/file_task_handler.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ def _fetch_logs_from_service(url: str, log_relative_path: str) -> Response:
175175
secret_key=get_signing_key("api", "secret_key"),
176176
# Since we are using a secret key, we need to be explicit about the algorithm here too
177177
algorithm="HS512",
178+
# We must set an empty private key here as otherwise it can be automatically loaded by JWTGenerator
179+
# and secret_key and private_key cannot be set together
180+
private_key=None, # type: ignore[arg-type]
178181
issuer=None,
179182
valid_for=conf.getint("webserver", "log_request_clock_grace", fallback=30),
180183
audience="task-instance-logs",

0 commit comments

Comments
 (0)