Repository navigation
Description
Apache Airflow Provider(s)
amazon
Versions of Apache Airflow Providers
apache-airflow-providers-amazon==9.18.0
Apache Airflow version
3..x.x
Operating System
Debian/Ubuntu-based containers (Astronomer Runtime, official Airflow images)
Deployment
Astronomer
Deployment details
Any deployment where the triggerer runs on a different host than the worker (Astronomer, MWAA, distributed Airflow with separate triggerer pods).
What happened
EksPodOperator with deferrable=True fails with 401 Unauthorized when the triggerer runs on a separate host from the worker (e.g., Astronomer, MWAA).
The root cause is that the credential temp file created during execute() is not available on the triggerer when it tries to poll the pod.
The credential lifecycle during deferral:
EksPodOperator.execute()callseks_hook.get_session()to extract AWS credentials_secure_credential_context()writes them to a temp file on the worker (e.g.,/tmp/tmpXYZ)generate_config_file()creates a kubeconfig with an exec block that references that temp file:users: - name: aws user: exec: command: sh args: ["-c", ". /tmp/tmpXYZ; python -m airflow...utils.eks_get_token ..."]
KubernetesPodOperator.invoke_defer_method()callsconvert_config_file_to_dict(), which reads the kubeconfig into a dict — including the exec block with the temp file path- The task defers, the context managers exit, and both temp files are deleted (the credential file and the kubeconfig file)
- The trigger is serialized to the metadata DB with
config_dictcontaining the now-stale temp file path - The triggerer (on a different host) deserializes the trigger and calls
load_kube_config_from_dict(config_dict) kubernetes_asyncioprocesses the exec block and runssh -c ". /tmp/tmpXYZ; ..."/tmp/tmpXYZdoesn't exist on the triggerer → credentials not loaded → 401 Unauthorized
Error output:
kubernetes_asyncio.client.exceptions.ApiException: (401)
Reason: Unauthorized
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure",
"message":"Unauthorized","reason":"Unauthorized","code":401}
Note: This is a separate issue from #60269 (POSIX shell compatibility). Even with the . fix from that issue, the credential temp file still won't exist on the triggerer.
Note: The trigger_reentry() path works correctly because it generates fresh credentials on the worker when the trigger fires. The problem is only during the triggerer's polling phase.
What you think should happen instead
The exec block in the serialized config_dict should not depend on temp files that only exist on the worker.
How to reproduce
- Deploy Airflow with a triggerer running on a separate host from the worker (Astronomer, MWAA, or distributed Helm deployment with dedicated triggerer pods)
- Configure an
EksPodOperatorwithdeferrable=Trueconnecting to an EKS cluster - Run the DAG
- The pod launches successfully (worker has valid credentials)
- The task defers to the triggerer
- The triggerer fails to poll the pod with 401 Unauthorized
Anything else
I used AI tools to help troubleshoot this and my understanding is still limited. Hoping some discussion can help determine the correct fix for which I'm happy to help with.
Are you willing to submit PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct
Activity
Codingaditya17 commentedon Feb 10, 2026
Thanks for the detailed and clear issue description.
I’d like to work on this. I’m currently going through the deferrable execution path and how credentials are serialized between the worker and trigger. I’ll share a proposed approach here before opening a PR to make sure it aligns with expectations.
andrewhharmon commentedon Feb 10, 2026
Great, thanks. You may want to look at this issue as well to see if it's related. #61737
Codingaditya17 commentedon Feb 10, 2026
I’ve submitted a PR addressing the related exec-based auth caching issue in #61737.
If no one is actively working on this issue, I’m happy to look into it.
amankum2004 commentedon Feb 14, 2026
@andrewhharmon Sir, if no one is working on this issue, can i work on this ?
Can it be assigned to me ?
andrewhharmon commentedon Mar 3, 2026
im not sure sounds like @Codingaditya17 said he'd take a look
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
fix(amazon): EksPodOperator deferrable mode fails on remote triggerers
mattwang44 commentedon Oct 19, 2026
This should be fixed on main by #64187 (amazon provider 9.25.0).
EksPodOperator.invoke_defer_methodnow defers to the newEksPodTrigger, which fetches fresh AWS credentials and regenerates the kubeconfig on the triggerer itself, so the triggerer no longer depends on the worker's temp file.test_run_generates_fresh_kubeconfigcovers this path.Could someone confirm on a split worker/triggerer deployment and close this?
Drafted-by: Claude Code (Opus 5.5); reviewed by @mattwang44 before posting
shahar1 commentedon Nov 6, 2026
Solved by #64187