[GH-ISSUE #5885] [bug]: authExchange creates infinite retry loop on permanent auth/refresh failure, flooding backend with requests #2314

Open
opened 2026-03-16 23:55:59 +03:00 by kerem · 4 comments
Owner

Originally created by @Leon-Luu on GitHub (Feb 17, 2026).
Original GitHub issue: https://github.com/hoppscotch/hoppscotch/issues/5885

Originally assigned to: @anwarulislam, @mirarifhasan on GitHub.

Is there an existing issue for this?

  • I have searched existing issues and this bug hasn't been reported yet

Platform

Web App

Browser

Chrome

Operating System

macOS

Bug Description

Description

When a user's refresh token is permanently invalid (expired, rotated, or cookie deleted), the authExchange in the GQL client enters an infinite retry loop that floods the backend with thousands of GET /v1/auth/refresh requests per minute.

Observed behavior:

Image

We had seen many times more than 16,000+ requests to from a single IP within ~10 minutes
All returning 404/403 (refresh token invalid)
Requests originated from a single browser session (Chrome 144, macOS)
The loop continued indefinitely until the user manually closed the tab

Root cause:

In GQLClient.ts, the authExchange configuration has no retry limit:

async refreshAuth() {
  const refresh = platform.auth.refreshAuthToken
  if (!refresh) return
  await refresh()  // No retry limit — called indefinitely on failure
},

When didAuthError() returns true, urql calls refreshAuth(). If the refresh fails (returns false), urql retries the original GQL operation, which fails auth again, triggering another refreshAuth() — creating an infinite loop.

Additionally, refreshToken() in index.ts silently swallows all errors and has no mechanism to stop retrying:

async function refreshToken() {
  try {
    const res = await axios.get(`${...}/auth/refresh`, { withCredentials: true })
    return res.status === 200
  } catch (_error) {
    return false  // Silently fails, caller retries indefinitely
  }
}

Impact:

  • Backend resource waste (thousands of unnecessary requests)
  • Potential rate-limiting or throttling of legitimate users sharing infrastructure
  • Poor user experience — the user is stuck in a broken session with no feedback
  • Cloud Run scaling costs from handling request floods

Proposed fix:

  • Add a consecutive failure counter to refreshAuth() in the authExchange— after 3 failed attempts, stop retrying and sign the user out
  • Add a matching counter to refreshToken() to short-circuit before making HTTP requests
  • Reset counters on successful refresh or login

Deployment Type

Self-hosted (on-prem deployment)

Version

2026.1.1

Originally created by @Leon-Luu on GitHub (Feb 17, 2026). Original GitHub issue: https://github.com/hoppscotch/hoppscotch/issues/5885 Originally assigned to: @anwarulislam, @mirarifhasan on GitHub. ### Is there an existing issue for this? - [x] I have searched existing issues and this bug hasn't been reported yet ### Platform Web App ### Browser Chrome ### Operating System macOS ### Bug Description **Description** When a user's refresh token is permanently invalid (expired, rotated, or cookie deleted), the [authExchange](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-backend/src/auth/auth.controller.ts) in the GQL client enters an infinite retry loop that floods the backend with thousands of **_GET /v1/auth/refresh_** requests per minute. **Observed behavior:** <img width="955" height="195" alt="Image" src="https://github.com/user-attachments/assets/ae70a8d8-e1df-48d5-affd-e3bf0fe5ef25" /> We had seen many times more than 16,000+ requests to from a single IP within ~10 minutes All returning 404/403 (refresh token invalid) Requests originated from a single browser session (Chrome 144, macOS) The loop continued indefinitely until the user manually closed the tab **Root cause:** In [GQLClient.ts](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-common/src/helpers/backend/GQLClient.ts), the authExchange configuration has no retry limit: ``` async refreshAuth() { const refresh = platform.auth.refreshAuthToken if (!refresh) return await refresh() // No retry limit — called indefinitely on failure }, ``` When _**didAuthError()**_ returns true, urql calls _**refreshAuth()**_. If the refresh fails (returns false), urql retries the original GQL operation, which fails auth again, triggering another **_refreshAuth()_** — creating an infinite loop. Additionally, **_refreshToken()_** in **_index.ts_** silently swallows all errors and has no mechanism to stop retrying: ``` async function refreshToken() { try { const res = await axios.get(`${...}/auth/refresh`, { withCredentials: true }) return res.status === 200 } catch (_error) { return false // Silently fails, caller retries indefinitely } } ``` **Impact:** - Backend resource waste (thousands of unnecessary requests) - Potential rate-limiting or throttling of legitimate users sharing infrastructure - Poor user experience — the user is stuck in a broken session with no feedback - Cloud Run scaling costs from handling request floods **Proposed fix:** - Add a consecutive failure counter to **_refreshAuth()_** in the _**authExchange**_— after 3 failed attempts, stop retrying and sign the user out - Add a matching counter to **refreshToken()** to short-circuit before making HTTP requests - Reset counters on successful refresh or login ### Deployment Type Self-hosted (on-prem deployment) ### Version 2026.1.1
Author
Owner

@Leon-Luu commented on GitHub (Mar 13, 2026):

@mirarifhasan @anwarulislam @jamesgeorge007 would be good if Hoppscotch team takes ownership to fix this issue instead of random users providing fix with ai without commitments of following up. This is core issue and important to fix I think.

<!-- gh-comment-id:4055264611 --> @Leon-Luu commented on GitHub (Mar 13, 2026): @mirarifhasan @anwarulislam @jamesgeorge007 would be good if Hoppscotch team takes ownership to fix this issue instead of random users providing fix with ai without commitments of following up. This is core issue and important to fix I think.
Author
Owner

@cB-Abhinav-Gautam commented on GitHub (Mar 16, 2026):

Any temporary fix?

<!-- gh-comment-id:4065475106 --> @cB-Abhinav-Gautam commented on GitHub (Mar 16, 2026): Any temporary fix?
Author
Owner

@matthewwalker1621-star commented on GitHub (Mar 16, 2026):

Any temporary fix untill then please

On Mon, Mar 16, 2026, 1:53 AM Abhinav Gautam @.***>
wrote:

cB-Abhinav-Gautam left a comment (hoppscotch/hoppscotch#5885)
https://github.com/hoppscotch/hoppscotch/issues/5885#issuecomment-4065475106

Any temporary fix?


Reply to this email directly, view it on GitHub
https://github.com/hoppscotch/hoppscotch/issues/5885#issuecomment-4065475106,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/B7GHLXGPMECAHR62DXBVBNT4Q6QGDAVCNFSM6AAAAACVMZH2HCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DANRVGQ3TKMJQGY
.
You are receiving this because you are subscribed to this thread.Message
ID: @.***>

<!-- gh-comment-id:4066540599 --> @matthewwalker1621-star commented on GitHub (Mar 16, 2026): Any temporary fix untill then please On Mon, Mar 16, 2026, 1:53 AM Abhinav Gautam ***@***.***> wrote: > *cB-Abhinav-Gautam* left a comment (hoppscotch/hoppscotch#5885) > <https://github.com/hoppscotch/hoppscotch/issues/5885#issuecomment-4065475106> > > Any temporary fix? > > — > Reply to this email directly, view it on GitHub > <https://github.com/hoppscotch/hoppscotch/issues/5885#issuecomment-4065475106>, > or unsubscribe > <https://github.com/notifications/unsubscribe-auth/B7GHLXGPMECAHR62DXBVBNT4Q6QGDAVCNFSM6AAAAACVMZH2HCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DANRVGQ3TKMJQGY> > . > You are receiving this because you are subscribed to this thread.Message > ID: ***@***.***> >
Author
Owner

@roopepaajanen commented on GitHub (Mar 16, 2026):

Redeploying the application during off hours clears out all idle connections and keeps failing traffic to a minimum, but this is only a temporary solution.

<!-- gh-comment-id:4066577969 --> @roopepaajanen commented on GitHub (Mar 16, 2026): Redeploying the application during off hours clears out all idle connections and keeps failing traffic to a minimum, but this is only a temporary solution.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hoppscotch#2314
No description provided.