Skip to content

App hangs on splash screen after refresh token is rejected (400) #1342

Description

@kemeen

Bug: App hangs on splash screen after refresh token is rejected (400) on second refresh

Summary

After a successful login, the app performs one silent token refresh successfully, but the next refresh attempt is rejected by the server with 400 Bad Request. From that point on, the app hangs indefinitely on the splash screen and eventually becomes unresponsive / crashes, rather than falling back to a login prompt.

Environment

  • App version: 2.0.4, build 250
  • Platform: iOS
  • Server: self-hosted, docker.io/wger/server:latest (wger 2.6 alpha branch), via the official wger-project/docker compose stack
  • Deployment: behind Nginx Proxy Manager → the bundled wger-nginx container → web/powersync containers
  • PowerSync self-hosted sync service in use (not the hosted wger.de sync)

Steps to reproduce

  1. Fresh login via username/password in the app against a self-hosted server.
  2. App performs an initial silent token refresh successfully.
  3. Wait roughly 4 minutes.
  4. App attempts another token refresh.
  5. Server responds 400 to /allauth/app/v1/tokens/refresh.
  6. App hangs on the splash screen and does not recover; eventually becomes unresponsive.

Actual behavior

Server logs show the clear pattern (nginx access log, timestamps ~4 minutes apart):
{"ts":"...14:38:22...","request_method":"POST","request_uri":"/allauth/app/v1/tokens/refresh",...,"status":200,"size":1459,...} {"ts":"...14:42:22...","request_method":"POST","request_uri":"/allauth/app/v1/tokens/refresh",...,"status":400,"size":15,...}

The first refresh succeeds; the second, ~4 minutes later, is rejected. After the 400, the app does not prompt for re-login — it hangs on the splash screen and eventually crashes.

Expected behavior

On a 400/invalid-refresh-token response, the app should clear the stored session and fall back to the login screen, rather than hanging indefinitely.

Suspected cause

This looks consistent with refresh token rotation: if the server issues a new refresh token on every successful refresh (invalidating the previous one) and the app isn't correctly persisting the newly-issued token from a successful refresh, the next refresh attempt would resend the now-invalidated token and get rejected. This reproduced independently in two separate sessions (once shortly after rotating the server's JWT signing keys — an expected one-time invalidation — and again afterward with a completely fresh login/token pair, ruling out the key rotation as the sole cause).

Additional notes

Reproducible and consistent across multiple attempts. Happy to provide additional logs (PowerSync/nginx/web) if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions