Expo Go 57.0.9 (Android): signing in does not authenticate project loading — session saved to expo_session, loader reads expo_auth_session → HTTP 403
Minimal reproducible example
No separate repository: the bug is in the Expo Go Android client, not in project code, and reproduces with any auth-required project. Source-level pointers (pinned to sdk-57):
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/services/SessionRepository.kt#L13-L47
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/home/HomeAppViewModel.kt#L393-L394
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/experience/HomeActivity.kt#L42
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/ExpoUpdatesAppLoader.kt#L345-L347
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/storage/ExponentSharedPreferences.kt#L65-L76
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/modules/ExponentKernelModule.kt#L93
- https://github.com/expo/expo/blob/d0c137db622ac5b32a4088846a92b8177427eec2/apps/expo-go/android/expoview/src/main/java/host/exp/exponent/home/UpdateRow.kt#L18-L22
Steps to reproduce
Platform: Android, environment: Expo Go 57.0.9 (Play Store, versionCode 445, "Supported SDKs: 57"). Package manager: npm.
- Have an Expo account that owns an SDK 57 project whose Expo Go access requires authentication (server returns
403: Experience "@owner/slug" is not viewable in Expo Go: this project requires authentication. Sign in to Expo Go with an Expo account that is a member of the account that owns this project.). - Publish an EAS Update to any branch (
eas update --branch <branch>). - On a physical Android device, open Expo Go without signing in and open the update link (
exp://u.expo.dev/<projectId>/group/<groupId>via QR, or the update permalinkexp://u.expo.dev/update/<updateId>). → "Uncaught Error: java.io.IOException: Failed to download remote update". Logcat:dev.expo.updates … "Remote update request not successful"(response is non-2xx). Reproducing the loader's request with curl from the same device gives the 403 above. - In Expo Go → Profile, sign in with the owner account. The home screen now lists the project and its branches (so the home screen is authenticated).
- Force-stop Expo Go, open the same link again (both the group URL and the update permalink were tried).
Expected: the update loads, like on iOS with the same account and the same Expo Go version (57.0.9, SDK 57), which opens these updates. Actual: exactly the same failure as before signing in, within ~0.6 s ("Remote update request not successful").
Why (from source, sdk-57 @ d0c137db622ac5b32a4088846a92b8177427eec2)
The Android home and the project loader use two different session stores:
- Sign-in in the new home writes the secret to
SessionRepository, SharedPreferences fileexpo_session, keysession_secret:experience/HomeActivity.kt:42→viewModel.onNewAuthSession(result.sessionSecret)home/HomeAppViewModel.kt:393-394→sessionRepository.saveSessionSecret(sessionSecret)services/SessionRepository.kt:13-19, 40
- The loader adds
Expo-SessionfromExponentSharedPreferences.sessionSecret, i.e. keyexpo_auth_session(JSON fieldsessionSecret):ExpoUpdatesAppLoader.kt:345-347storage/ExponentSharedPreferences.kt:65-76, 106, 148
- The only writer of
expo_auth_sessionis the legacy kernel module:modules/ExponentKernelModule.kt:93→exponentSharedPreferences.updateSession(it). The new home never calls it.
So after signing in on Android, the manifest request is still sent without Expo-Session and the server keeps answering 403. Same code on main (ExpoUpdatesAppLoader.kt:346-348).
Server-side check (no session, same update, from the device network): Expo-Client-Environment: EXPO_DEVICE → 403 (message above) for both expo-platform: android and ios; EXPO_SIMULATOR → 200. That is also why an Android emulator loads the update without signing in, which makes the bug invisible in emulator testing.
Related, separate observation
In the branch update list, Android marks every update of a project with a non-SDK runtimeVersion (policy appVersion, 0.1.0) as "Not compatible with this version of Expo Go" and makes the row non-clickable: home/UpdateRow.kt:18-20 compares the first segment of runtimeVersion ("0") with the SDK major ("57"). iOS (BranchDetailsView.swift) checks expoGoSDKVersion instead and opens the same updates. (Similar to #46846, but here the parsing is not the issue — Android compares a different field than iOS.)
Environment
expo-env-info 2.1.0 environment info:
System: OS: macOS 26.6.2
Binaries: Node: 25.7.0, npm: 11.10.1
npmPackages:
expo: 57.0.20
expo-updates: 57.0.21
react-native: 0.86.3
Expo Workflow: managed
Device: Xiaomi Pad 5 (nabu), Android 13, Expo Go 57.0.9 (445)
iOS device for comparison: Expo Go 57.0.9, SDK 57
Expo Doctor Diagnostics
Running 21 checks on your project...
19/21 checks passed. 2 checks failed.
✖ Check for legacy global CLI installed locally (eas-cli in project dependencies)
✖ Check that packages match versions required by installed Expo SDK
patch mismatches only, e.g. expo ~57.0.23 expected, 57.0.20 found
Both failures concern the app project; the bug above is in the Expo Go client and does not depend on them.
Source: expo/expo