You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
load_incluster_config() sets api_key['authorization'] but auth_settings() expects api_key['BearerToken'] in v36 #2584
After upgrading from kubernetes==35.0.0 to kubernetes==36.0.0, all API calls from pods using load_incluster_config() fail with 401 Unauthorized. The Bearer token is never sent in the Authorization header.
Root cause
In v36, Configuration.auth_settings() (auto-generated) checks for api_key['BearerToken']:
But InClusterConfigLoader._set_config() (manually maintained in kubernetes/base/) still sets the old key:
def_set_config(self, client_configuration):
client_configuration.host=self.hostclient_configuration.ssl_ca_cert=self.ssl_ca_certifself.tokenisnotNone:
client_configuration.api_key['authorization'] =self.token# <-- old key
Since auth_settings() looks for 'BearerToken' and load_incluster_config sets 'authorization', the token is never picked up by ApiClient.update_params_for_auth(), so no Authorization header is sent.
In v35, auth_settings() checked for 'authorization', so both sides agreed and everything worked.
How to reproduce
# Inside a pod with a service accountfromkubernetesimportclient, configconfig.load_incluster_config()
v1=client.CoreV1Api()
v1.list_namespaced_pod('default', limit=1)
# => kubernetes.client.exceptions.UnauthorizedException: (401)
Verified that the token itself is valid — a direct urllib.request call with the same token from /var/run/secrets/kubernetes.io/serviceaccount/token returns 200.
Expected behavior
load_incluster_config() should set api_key['BearerToken'] (matching what auth_settings() expects), or auth_settings() should check for api_key['authorization'] (matching what load_incluster_config sets).
Environment
Kubernetes cluster version: 1.31
Python version: 3.13.12
kubernetes client version: 36.0.0 (works fine on 35.0.0)
We had a similar issue, while trying to run a PATCH to a Pod using default service account. RBAC was properly set. Downgrading to 35.0.0 also fixed the issue for us {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}
Reacted by Nick Lederman, Matt Banak, Hank Huang, tolsadus and Tewfik Ghariani
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.
We encountered the same class of in-cluster authentication failure in a Python 3.13-based Kubernetes application.
After investigating the behavior described in this issue, I implemented an application-level defensive approach where the Kubernetes ApiClient is constructed explicitly instead of relying entirely on load_incluster_config().
The implementation explicitly configures:
Kubernetes API server from KUBERNETES_SERVICE_HOST / KUBERNETES_SERVICE_PORT
ServiceAccount Bearer token from /var/run/secrets/kubernetes.io/serviceaccount/token
Kubernetes CA certificate from /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
TLS certificate verification enabled
The important part is that the Bearer token is configured using the authentication key expected by the generated client configuration, rather than relying on the implicit mapping performed by load_incluster_config().
I have documented the approach and added unit tests here:
This is not intended as a replacement for the upstream fix. It is an application-level defensive pattern for applications that want explicit control over in-cluster authentication and early validation of ServiceAccount credentials.
Hopefully this is useful to others who encounter similar authentication regressions during Kubernetes Python client upgrades.
Activity
MatanKoby commentedon May 21, 2026
Happened to me too.
Modifiying lines 528-530 in file kubernetes/base/config/kube_config.py:
def _set_config(self, client_configuration): if 'token' in self.__dict__: client_configuration.api_key['authorization'] = self.tokeninto
def _set_config(self, client_configuration): if 'token' in self.__dict__: client_configuration.api_key['authorization'] = self.token client_configuration.api_key['BearerToken'] = self.tokenis an instant fix for me.
EDIT: Downgrading to v35 is obviously a better fix till a fix is merged, just to mention.
exherb commentedon May 21, 2026
crazy bug.
faust64 commentedon May 21, 2026
... or 33.1.0, if you were impacted by the no_proxy regression that should finally be fixed in 36.0.0.
or give up and rewrite your code using reliable libraries, like requests ...
fix(ingestion): cap kubernetes client below 36.0.0 (#28331)
fix(ingestion): cap kubernetes client below 36.0.0 (#28331)
fix(ingestion): cap kubernetes client below 36.0.0 (#28331)
[Kubernetes] Pin kubernetes<36 due to RBAC regression from the package (
saviomuniz commentedon May 21, 2026
We had a similar issue, while trying to run a PATCH to a Pod using default service account. RBAC was properly set. Downgrading to 35.0.0 also fixed the issue for us
{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}roycaihw commentedon May 21, 2026
This is a duplicate of #2582 and is being fixed in #2585
[Kubernetes] Pin kubernetes<36 due to RBAC regression from the package (
fix(python-k8s): Pin `kubernetes` package version for now (#813)
yliaog commentedon May 26, 2026
https://github.com/kubernetes-client/python/releases/tag/v36.0.1 has been released, it should fix the issue. Could you please give it a try?
soheilxor commentedon May 28, 2026
I can confirm that the fix worked on our cluster.
chore: Pin kubernetes below v36 to avoid breaking API changes (#259)
yliaog commentedon Jun 1, 2026
https://github.com/kubernetes-client/python/releases/tag/v36.0.2 has been released, please check if it helps fix the problem.
yliaog commentedon Jun 1, 2026
/close
k8s-ci-robot commentedon Jun 1, 2026
@yliaog: Closing this issue.
Details
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.
amolpratap-singh commentedon Aug 29, 2026
Application-level defensive approach
We encountered the same class of in-cluster authentication failure in a Python 3.13-based Kubernetes application.
After investigating the behavior described in this issue, I implemented an application-level defensive approach where the Kubernetes
ApiClientis constructed explicitly instead of relying entirely onload_incluster_config().The implementation explicitly configures:
KUBERNETES_SERVICE_HOST/KUBERNETES_SERVICE_PORT/var/run/secrets/kubernetes.io/serviceaccount/token/var/run/secrets/kubernetes.io/serviceaccount/ca.crtThe important part is that the Bearer token is configured using the authentication key expected by the generated client configuration, rather than relying on the implicit mapping performed by
load_incluster_config().I have documented the approach and added unit tests here:
https://github.com/amolpratap-singh/kubernetes-incluster-auth
This is not intended as a replacement for the upstream fix. It is an application-level defensive pattern for applications that want explicit control over in-cluster authentication and early validation of ServiceAccount credentials.
Hopefully this is useful to others who encounter similar authentication regressions during Kubernetes Python client upgrades.