◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 34 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 34 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-10-27Intermediate

Your EAS Update Opens in Expo Go on iPhone but Stops on Android with "Failed to download remote update". The 403 You Get Even When Signed In

An EAS Update that opens in Expo Go on iOS but stops on Android (SDK 57) with Failed to download remote update. The cause is a sign-in token saved in one place and read from another, and the fix sits on the SDK 58 side. The order to check things in, and what to run yourself.

Rork603Expo Go6EAS Update8Android62Troubleshooting50SDK 57

You publish an EAS Update, scan the QR code from the dashboard with Expo Go on your iPhone, and the app opens. You scan the same QR code with Expo Go on an Android phone, and a red screen shows a single line before everything stops.

Uncaught Error: java.io.IOException: Failed to download remote update

"View error log" shows that same line and nothing else: no HTTP status, no name for the asset that failed. You rebuild the update, clear caches, reinstall Expo Go, and end up back on the same screen. If that's your evening right now, here is what has been reported about the cause, and the order I'd check things in.

Draw one line first: suspect Expo Go, not the update

I ship wallpaper apps on both iOS and Android, so when only one platform behaves differently my first instinct is to blame my own configuration. This bug punishes that instinct.

There is a report on the Expo repository that matches this exactly (expo/expo#50139). It uses a blank create-expo-app project on SDK 57 with only expo-updates added. The same update group opened on iOS and failed on two Android phones. Five dependencies, one asset; there is almost nothing in the project to suspect.

So I'd check these four things, in this order.

What to checkWhat the answer tells you
Does the same update open in Expo Go on iOS?If yes, the update itself is healthy. Look at the Android-only path.
Is the Android device real or an emulator?If it opens on the emulator and fails only on a real phone, you are likely in this bug.
Which Expo Go version?57.0.9, the build for SDK 57, is where it was reported. The 58 line is a different story, below.
What HTTP status does the server return?403 means you are turned away before loading starts. 404 means the update group or runtime version is wrong.

If the first two come back "yes", it is reasonable to stop suspecting assets and bundles and start suspecting what Expo Go puts in its request.

The cause: the sign-in token lived in two places

A second report (expo/expo#50253) traces it down to specific source lines.

After the Android home screen was rewritten, Expo Go started saving your sign-in secret to a store called expo_session. The code that loads an update kept reading an older store, expo_auth_session. The only thing that ever wrote to that older store was the previous home screen, which the rewrite removed.

So when you sign in from the profile tab, the home screen lists your projects and branches correctly. On screen, you are authenticated. But the requests that fetch the manifest and assets go out with no Expo-Session header.

According to the report, the server answers with this 403:

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.

The reporter says that even after signing in and reopening the same link, the same failure came back in about 0.6 seconds. The fix PR (expo/expo#50498) also explains why this stayed hidden for so long: the server only recently began requiring ownership to load updates in Expo Go, and emulators identify themselves as EXPO_SIMULATOR, which the server doesn't gate. That matches "works on the emulator, fails on the real phone".

Being signed in on screen and loading with the same key are two different things.

Two things to run yourself

The first is a small script that asks the server whether the update group is visible per platform, without Expo Go in the way. It sends the same kind of request with curl.

#!/usr/bin/env bash
# Usage: ./manifest_probe.sh <projectId> <groupId> <SDK major number>
set -euo pipefail
PID="${1:?projectId}"; GID="${2:?groupId}"; SDK="${3:?sdk major}"
URL="https://u.expo.dev/${PID}/group/${GID}"
for P in ios android; do
  CODE=$(curl -sS -m 20 -o "/tmp/probe_${P}.txt" -w '%{http_code}' "$URL" \
    -H "expo-platform: ${P}" \
    -H "expo-runtime-version: exposdk:${SDK}.0.0" \
    -H "accept: multipart/mixed")
  echo "${P}: HTTP ${CODE}"; head -c 300 "/tmp/probe_${P}.txt"; echo
done

When I ran it with IDs that don't exist, this is what came back.

ios: HTTP 404
There is no update identified by group ID "11111111-1111-4111-8111-111111111111" and platform "ios"
android: HTTP 404
There is no update identified by group ID "11111111-1111-4111-8111-111111111111" and platform "android"

Reading it is simple. If both are 200, the update exists on the server for both platforms. If only one is 404, the eas update for that platform didn't go through. If both are fine and only Expo Go on Android fails, the problem is in what Expo Go sends, not in your update. Note that this script carries no Expo Go sign-in, so it won't reproduce the 403. Its job is to rule out a missing group or a mismatched runtime version first.

The second is for a real Android phone: read the Expo Go version and pull the failure line.

# Check the Expo Go version, then pull only the load-failure line
adb shell dumpsys package host.exp.exponent | grep versionName
adb logcat -d | grep -i "Remote update request not successful"

If that line is in the log, the server received the request and answered with something other than 2xx. That is the fact the one-line error screen leaves out. I haven't run these two commands, because I have no Android phone connected here; I wrote them from the description in the report.

When does it get fixed? Only what I could confirm

The fix PR was merged into main on 2026-09-23, which I read from the PR's state. I then compared the actual source on the two branches.

BranchWhere the update request reads the session from
sdk-57Still the old store (`exponentSharedPreferences.sessionSecret`)
sdk-58Changed to read the new store (`sessionRepository`)

The last Expo Go for SDK 57 is 57.0.9 (published 2026-08-15), and I couldn't find a newer 57 build. So with SDK 57 and Expo Go on Android, opening an update that requires ownership looks unfixed for now. Expo Go on the 58 line (58.0.7 was published on 2026-10-24) contains the fix in source. I haven't confirmed behavior on a real phone with the store build of 58, and I'd rather say so than imply it.

The ways around it either skip the Expo Go loader or change which path you take.

  • Check on Expo Go for iOS. In the report, the same update opens there.
  • Check on an Android emulator. Per the PR, the server doesn't gate emulators.
  • Apply the update to an app you built yourself (a development build or an internal-distribution build) instead of Expo Go. The bug is inside Expo Go's update loader, so that path doesn't go through it.
  • Move to SDK 58 and test with Expo Go for 58. The migration is large, so I wouldn't do it just for this.

Which one fits depends on your situation. Just knowing that the update isn't broken is enough to stop the rebuild-and-republish loop.

If you want to sort through the other ways an update fails to show up, there is five typical patterns when an EAS Update doesn't appear. The order for checking the Expo Go sign-in itself is in the two logins to check first when Expo Go stops opening your preview.

Next time only Android disagrees with iOS, try these two checks before you rebuild anything: does it open on iOS, and is the Android device real or an emulator? I'm putting those two at the top of my own checklist for platform-only differences.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-10-21
A Widget That Updates on Time in iOS Stays on "Initial" in Android
In expo-widgets, updateTimeline does nothing on Android and the generated XML hardcodes updatePeriodMillis to 0. How to recognize it, what updateSnapshot can cover, and a script to check your project.
⬡ Dev Tools2026-10-15
When EXPO_PUBLIC_ Values Read Fine in Dev but Come Back undefined in Production: Telling the Spellings Apart
The API URL reads fine while developing and turns undefined once the app is built. The cause was how process.env was written. I lined up babel-preset-expo's output for dev and production and tabulated which spellings get replaced and which are left behind.
⬡ Dev Tools2026-10-07
Japanese Headings Won't Turn Bold on Android: How to Trace and Fix a fontWeight That Does Nothing
A troubleshooting note for Rork apps where headings look bold on iPhone but stay thin on Android. How to tell the symptoms apart, pick weights through fontFamily, and verify the fix.