Repository navigation
Closed
Labels
authpriority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
Determine this is the right repository
- I determined this is the correct repository in which to report this bug.
Summary of the issue
Faulty logic results in a bug. Here is a fix:
.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py
if use_mtls:
# Ensure the request has a session to mount the adapter to.
- if not request.session:
+ if not hasattr(request, "session") or not request.session:
request.session = requests.Session()API client name and version
google-genai==1.66.0
Reproduction steps: code
from google import genai
from google.genai import types
client = genai.Client(
vertexai=True,
project='...",
location='global',
)
chat = client.chats.create(model='gemini-3-pro-preview')
response = chat.send_message("Hello. What is 2+2?")Python environment
python 3.14
Python dependencies
[project]
name = "..."
version = "0.1.0"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"google-genai==1.66.0",
"ipykernel>=7.2.0",
"jupyter>=1.1.1",
]
Additional context
Error Log:
Details
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/chats.py:252, in Chat.send_message(self, message, config)
247 raise ValueError(
248 f"Message must be a valid part type: {types.PartUnion} or"
249 f" {types.PartUnionDict}, got {type(message)}"
250 )
251 input_content = t.t_content(message)
--> [252](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/chats.py:252) response = self._modules.generate_content(
253 model=self._model,
254 contents=self._curated_history + [input_content], # type: ignore[arg-type]
255 config=config if config else self._config,
256 )
257 model_output = (
258 [response.candidates[0].content]
259 if response.candidates and response.candidates[0].content
260 else []
261 )
262 automatic_function_calling_history = (
263 response.automatic_function_calling_history
264 if response.automatic_function_calling_history
265 else []
266 )
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/models.py:[5644](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/models.py:5644), in Models.generate_content(self, model, contents, config)
5642 while remaining_remote_calls_afc > 0:
5643 i += 1
-> 5644 response = self._generate_content(
5645 model=model, contents=contents, config=parsed_config
5646 )
5648 function_map = _extra_utils.get_function_map(parsed_config)
5649 if not function_map:
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/models.py:4306, in Models._generate_content(self, model, contents, config)
4303 request_dict = _common.convert_to_dict(request_dict)
4304 request_dict = _common.encode_unserializable_types(request_dict)
-> [4306](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/models.py:4306) response = self._api_client.request(
4307 'post', path, request_dict, http_options
4308 )
4310 if config is not None and getattr(
4311 config, 'should_return_http_response', None
4312 ):
4313 return_value = types.GenerateContentResponse(sdk_http_response=response)
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1401, in BaseApiClient.request(self, http_method, path, request_dict, http_options)
1391 def request(
1392 self,
1393 http_method: str,
(...) 1396 http_options: Optional[HttpOptionsOrDict] = None,
1397 ) -> SdkHttpResponse:
1398 http_request = self._build_request(
1399 http_method, path, request_dict, http_options
1400 )
-> [1401](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1401) response = self._request(http_request, http_options, stream=False)
1402 response_body = (
1403 response.response_stream[0] if response.response_stream else ''
1404 )
1405 return SdkHttpResponse(headers=response.headers, body=response_body)
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1237, in BaseApiClient._request(self, http_request, http_options, stream)
1234 retry = tenacity.Retrying(**retry_kwargs)
1235 return retry(self._request_once, http_request, stream) # type: ignore[no-any-return]
-> [1237](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1237) return self._retry(self._request_once, http_request, stream)
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:470, in Retrying.__call__(self, fn, *args, **kwargs)
468 retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
469 while True:
--> [470](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:470) do = self.iter(retry_state=retry_state)
471 if isinstance(do, DoAttempt):
472 try:
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:371, in BaseRetrying.iter(self, retry_state)
369 result = None
370 for action in self.iter_state.actions:
--> [371](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:371) result = action(retry_state)
372 return result
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:413, in BaseRetrying._post_stop_check_actions.<locals>.exc_check(rs)
411 retry_exc = self.retry_error_cls(fut)
412 if self.reraise:
--> [413](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:413) raise retry_exc.reraise()
414 raise retry_exc from fut.exception()
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:184, in RetryError.reraise(self)
182 def reraise(self) -> t.NoReturn:
183 if self.last_attempt.failed:
--> [184](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:184) raise self.last_attempt.result()
185 raise self
File ~/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/concurrent/futures/_base.py:443, in Future.result(self, timeout)
441 raise CancelledError()
442 elif self._state == FINISHED:
--> [443](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/concurrent/futures/_base.py:443) return self.__get_result()
445 self._condition.wait(timeout)
447 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
File ~/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/concurrent/futures/_base.py:395, in Future.__get_result(self)
393 if self._exception is not None:
394 try:
--> [395](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/concurrent/futures/_base.py:395) raise self._exception
396 finally:
397 # Break a reference cycle with the exception in self._exception
398 self = None
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:473, in Retrying.__call__(self, fn, *args, **kwargs)
471 if isinstance(do, DoAttempt):
472 try:
--> [473](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/tenacity/__init__.py:473) result = fn(*args, **kwargs)
474 except BaseException: # noqa: B902
475 retry_state.set_exception(sys.exc_info()) # type: ignore[arg-type]
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1180, in BaseApiClient._request_once(self, http_request, stream)
1178 # If using proj/location, fetch ADC
1179 if self.vertexai and (self.project or self.location):
-> [1180](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1180) http_request.headers['Authorization'] = f'Bearer {self._access_token()}'
1181 if self._credentials and self._credentials.quota_project_id:
1182 http_request.headers['x-goog-user-project'] = (
1183 self._credentials.quota_project_id
1184 )
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1008, in BaseApiClient._access_token(self)
1006 with self._sync_auth_lock:
1007 if not self._credentials:
-> [1008](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:1008) self._credentials, project = load_auth(project=self.project)
1009 if not self.project:
1010 self.project = project
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:191, in load_auth(project)
185 ## Set GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES to false
186 ## to disable bound token sharing. Tracking on
187 ## https://github.com/googleapis/python-genai/issues/1956
188 os.environ['GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES'] = (
189 'false'
190 )
--> [191](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/genai/_api_client.py:191) credentials, loaded_project_id = google.auth.default( # type: ignore[no-untyped-call]
192 scopes=['https://www.googleapis.com/auth/cloud-platform'],
193 )
195 if not project:
196 project = loaded_project_id
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:718, in default(scopes, request, quota_project_id, default_scopes)
706 checkers = (
707 # Avoid passing scopes here to prevent passing scopes to user credentials.
708 # with_scopes_if_required() below will ensure scopes/default scopes are
(...) 714 lambda: _get_gce_credentials(request, quota_project_id=quota_project_id),
715 )
717 for checker in checkers:
--> [718](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:718) credentials, project_id = checker()
719 if credentials is not None:
720 credentials = with_scopes_if_required(
721 credentials, scopes, default_scopes=default_scopes
722 )
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:714, in default.<locals>.<lambda>()
700 from google.auth.credentials import CredentialsWithQuotaProject
702 explicit_project_id = os.environ.get(
703 environment_vars.PROJECT, os.environ.get(environment_vars.LEGACY_PROJECT)
704 )
706 checkers = (
707 # Avoid passing scopes here to prevent passing scopes to user credentials.
708 # with_scopes_if_required() below will ensure scopes/default scopes are
709 # safely set on the returned credentials since requires_scopes will
710 # guard against setting scopes on user credentials.
711 lambda: _get_explicit_environ_credentials(quota_project_id=quota_project_id),
712 lambda: _get_gcloud_sdk_credentials(quota_project_id=quota_project_id),
713 _get_gae_credentials,
--> [714](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:714) lambda: _get_gce_credentials(request, quota_project_id=quota_project_id),
715 )
717 for checker in checkers:
718 credentials, project_id = checker()
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:410, in _get_gce_credentials(request, quota_project_id)
407 if request is None:
408 request = google.auth.transport._http_client.Request()
--> [410](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/_default.py:410) if _metadata.is_on_gce(request=request):
411 # Get the project ID.
412 try:
413 project_id = _metadata.get_project_id(request=request)
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:135, in is_on_gce(request)
132 if _NO_GCE_CHECK:
133 return False
--> [135](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:135) if ping(request):
136 return True
138 if os.name == "nt":
139 # TODO: implement GCE residency detection on Windows
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:205, in ping(request, timeout, retry_count)
192 """Checks to see if the metadata server is available.
193
194 Args:
(...) 202 bool: True if the metadata server is reachable, False otherwise.
203 """
204 use_mtls = _mtls.should_use_mds_mtls()
--> [205](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:205) _prepare_request_for_mds(request, use_mtls=use_mtls)
206 # NOTE: The explicit ``timeout`` is a workaround. The underlying
207 # issue is that resolving an unknown host on some networks will take
208 # 20-30 seconds; making this timeout short fixes the issue, but
209 # could lead to false negatives in the event that we are on GCE, but
210 # the metadata resolution was particularly slow. The latter case is
211 # "unlikely".
212 headers = _METADATA_HEADERS.copy()
File ~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:180, in _prepare_request_for_mds(request, use_mtls)
177 # Only modify the request if mTLS is enabled.
178 if use_mtls:
179 # Ensure the request has a session to mount the adapter to.
--> [180](https://vscode-remote+ssh-002dremote-002bgcp-002dwbi-002dsaksham-002dsdx-002dusc1-002d01.vscode-resource.vscode-cdn.net/home/ext_saksham_goyal_compassdigital/data-eng-des-projects/npc/~/data-eng-des-projects/npc/.venv/lib/python3.14/site-packages/google/auth/compute_engine/_metadata.py:180) if not request.session:
181 request.session = requests.Session()
183 adapter = _mtls.MdsMtlsAdapter()
AttributeError: 'Request' object has no attribute 'session'Reacted by Vitaliy Demidov and Jonathon Reinhart
Metadata
Metadata
Assignees
Labels
authpriority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Activity
Aramack commentedon Mar 6, 2026
I'm encountering the same error. This was a bug introduced in googleapis/google-auth-library-python@0387bb9.
It will default to checking if the
/run/google-mds-mtls/root.crtexists. It appears that this was recently added to the google base images (I'm seeing it on the debian base image personally). It will then use MTLS for connections to the metadata server which triggers the buggy code path.The three fixes I've found:
GCE_METADATA_MTLS_MODE=none.disable-https-mds-setup=trueat the instance or project (https://docs.cloud.google.com/compute/docs/metadata/overview#https-mds-disabling-certificate-setup).sakshamgoyal-01 commentedon Mar 6, 2026
@Aramack
Do I need to do all 3 of those?
Aramack commentedon Mar 6, 2026
No you don't need all three. Any one should resolve it.
This disables the feature in python.
This removes the feature from your python environment. I would not receommend it as you'll stop getting other security fixes.
This tell compute engine not to create the
/run/google-mds-mtls/root.crtcertificate. So the feature returns to being disabled.daniel-sanche commentedon Mar 6, 2026
Thanks for reporting this, I'll make sure it gets into the next release
daniel-sanche commentedon Mar 9, 2026
Looking at this a bit more, I'm not sure if it's safe to attach
request.session = requests.Session()to a requests object that wasn't designed to work with sessions. It seems like that could add confusion or bugs down the lineI'm thinking we should make
_prepare_request_for_mdsignore unsupported requests. But I'm still doing some research into the context of this change. Let me know if you have any thoughts on thisfix(auth): fix request session error (googleapis#16050)
daniel-sanche commentedon Mar 12, 2026
I merged a potential fix, but it sounds like there are some discussions about moving this request to use requests instead of http_client in #16076. I wasn't able to reproduce that issue, but I'll leave this open until I can confirm
tonyay163 commentedon Mar 12, 2026
@daniel-sanche when will we get a release
daniel-sanche commentedon Mar 12, 2026
There should be a release going out today
Edit: release is out: https://pypi.org/project/google-auth/2.49.1/
daniel-sanche commentedon Mar 12, 2026
It looks like there's still an issue when installed without the
requestsoptional dependency. I'll put together another fix for thatfix(auth): check hasattr before accessing request.session Fixes googl…
start-pm2: enable keyless GCS ADC + work around google-auth mTLS bugs
start-pm2: enable keyless GCS ADC + work around google-auth mTLS bugs
daniel-sanche commentedon May 5, 2026
The Compute Engine code requires requests, so this issue should be resolved:
google-cloud-python/packages/google-auth/google/auth/_default.py
Line 394 in dea5a53