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
On a self-hosted setup the Android app intermittently fails to finish syncing when opened. When it happens, the only reliable recovery is clearing the app storage and logging in again — restarting the app or waiting does not help. It is intermittent, which points at accumulated client state rather than every launch.
Environment
wger server 2.7.0a1 (self-hosted, docker), PowerSync service journeyapps/powersync-service:latest
The server-issued PowerSync JWT has a 600 s lifetime, so the client must refresh it every ~10 min. In the instance I captured, the 401 self-healed: right after PSYNC_S2103 there is a fresh POST /sync/stream → Sync stream started → new checkpoint → Sync stream complete. So the normal refresh path works.
Hypothesis
The permanent stalls appear to be the subset where, after the token expires (e.g. the app resumes from the background more than 10 min later), the client does not recover the stream — the credential refresh / reconnect after PSYNC_S2103 occasionally fails, and it stays down until a full storage-clear + re-login rebuilds the whole token chain. I could not capture the fatal stall directly in the server logs (the captured expiry recovered), so this part is inferred from the symptom (only re-login fixes it) rather than proven server-side.
Questions / asks
On PSYNC_S2103 (token expired) mid-stream, does the connector reliably call fetchCredentials() and reconnect, or can it get wedged holding a stale token until the local state is wiped?
Would it help to proactively refresh the PowerSync token before expiry given the short 600 s server default?
Related
I opened wger-project/wger#2428 to make the server token lifetime configurable (default unchanged at 600 s). Raising it is a palliative that reduces how often the client sits with an expired token on resume, but the underlying client recovery on PSYNC_S2103 is the actual fix and belongs here.
Summary
On a self-hosted setup the Android app intermittently fails to finish syncing when opened. When it happens, the only reliable recovery is clearing the app storage and logging in again — restarting the app or waiting does not help. It is intermittent, which points at accumulated client state rather than every launch.
Environment
journeyapps/powersync-service:latestpowersync-dart-core/2.3.0(Dart 3.12.2, Android)Server-side evidence (all infra healthy)
I went through the self-hosted stack and ruled infra out:
wal_level=logical, replication slot active /reserved./ps/path: buffering off, read/send timeout 24 h (long-lived stream is fine).PSYNC_S2305events (the Nutrition logbook becomes unusable when PowerSync user_ingredients fails with PSYNC_S2305 #1237 bucket issue is not involved here; themax_parameter_query_resultsworkaround is in place).The only recurring error in the PowerSync logs is the auth token expiring:
```
errorData: {code: PSYNC_S2103, description: "JWT has expired", status: 401}, route: /sync/stream
tokenDetails: payload {sub: 2, iat: ..., aud: powersync, exp: iat+600}
```
The server-issued PowerSync JWT has a 600 s lifetime, so the client must refresh it every ~10 min. In the instance I captured, the 401 self-healed: right after
PSYNC_S2103there is a freshPOST /sync/stream→Sync stream started→ new checkpoint →Sync stream complete. So the normal refresh path works.Hypothesis
The permanent stalls appear to be the subset where, after the token expires (e.g. the app resumes from the background more than 10 min later), the client does not recover the stream — the credential refresh / reconnect after
PSYNC_S2103occasionally fails, and it stays down until a full storage-clear + re-login rebuilds the whole token chain. I could not capture the fatal stall directly in the server logs (the captured expiry recovered), so this part is inferred from the symptom (only re-login fixes it) rather than proven server-side.Questions / asks
PSYNC_S2103(token expired) mid-stream, does the connector reliably callfetchCredentials()and reconnect, or can it get wedged holding a stale token until the local state is wiped?Related
I opened wger-project/wger#2428 to make the server token lifetime configurable (default unchanged at 600 s). Raising it is a palliative that reduces how often the client sits with an expired token on resume, but the underlying client recovery on
PSYNC_S2103is the actual fix and belongs here.