Skip to content

auth: AsyncAuthorizedSession.request leaks response across retry attempts #18315

Description

@nbayati

In google.auth.aio.transport.sessions.AsyncAuthorizedSession.request (packages/google-auth/google/auth/aio/transport/sessions.py:339-347), the retry loop reassigns response = await with_timeout(...) across retry attempts without closing the previous response.

If the response payload hasn't reached EOF before the next retry fires (e.g., with chunked or streaming responses), aiohttp keeps the socket checked out in connector._acquired. The transport protocol's internal EOF callback holds a bound reference to ClientResponse._response_eof, which prevents Python's garbage collector from cleaning up the orphaned response while the connection is waiting for data. Under concurrency, multiple requests retrying against a degraded endpoint can quickly burn through the connector pool (limit=100) and block other outgoing requests across the session.

Proposed Fix

Close any previous response before kicking off the next retry attempt, matching the pattern already used in sessions.py:L501-L518:

response = None
async for _ in retries:
    if response is not None and hasattr(response, "close"):
        try:
            res = response.close()
            if inspect.isawaitable(res):
                await res
        except Exception:
            pass

    response = await with_timeout(
        self._auth_request(
            url, method, data, request_headers, actual_timeout, **kwargs
        )
    )

    if response.status_code not in transport.DEFAULT_RETRYABLE_STATUS_CODES:
        break

Unit tests should check that when a retryable status code (like a 503) is followed by a 200, close() is awaited on the initial response before the retry runs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    authpriority: p2Moderately-important priority. Fix may not be included in next release.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions