Skip to content
Malik Hamza Shabbir
Mobile Developmentreact-nativeandroidgoogle-play16kb-page-size

Google Play 16KB Page Size: Fix Failing React Native Builds

HSMalik Hamza Shabbir7 min read

In short

As of June 10, 2026, Google Play blocks every update to an Android app whose native libraries are not aligned for 16KB memory pages, and React Native apps with stale native dependencies are failing that check daily. The May 1, 2026 deadline covered all updates to existing apps, and the Play Console extension option expired on May 31, 2026, so there is no deferral left to request. The fix rests on four pillars: React Native 0.77+, Android Gradle Plugin 8.5.1+ (8.7.0 recommended), NDK r28, and updated versions of the handful of native dependencies that are actually failing. Across the four client apps I have repaired, the fastest fix took 90 minutes and the median was about half a day.

Google Play 16KB Page Size: Fix Failing React Native Builds - branded cover card by Hamza Shabbir
On this page

What changed, and why is my update suddenly blocked?

Newer Android devices use 16KB memory pages instead of 4KB, and native libraries compiled with 4KB assumptions crash with segmentation faults on 16KB devices. Google Play enforces 16KB support at upload time, and since May 1, 2026 that enforcement covers every update to every existing app. The final extension window closed on May 31, 2026.

A memory page is the smallest unit of memory the kernel hands out. ARM64 hardware supports both 4KB and 16KB pages, and devices like the Pixel 8 and newer running Android 15+ can boot with a 16KB kernel because Google measured real launch and battery gains from larger pages. Every ELF shared library (.so file) declares its segment alignment when it is compiled. A library aligned to 4KB boundaries cannot be mapped safely by a 16KB kernel, so the dynamic loader fails or the process dies with SIGSEGV.

Here is the full timeline, all of it now behind us:





This is a platform requirement, not a React Native weakness. Flutter teams ran the same dependency audit across their plugin ecosystem, which is worth keeping in mind if you read my comparison of React Native vs Flutter for startup MVPs : both stacks inherit this class of problem from their native layers.

What exact errors am I seeing, and what is the difference between them?

There are two distinct failure modes with one root cause. The Play Console rejection reads "Your app is affected by Google Play's 16 KB page size requirements" and blocks the release at upload. The runtime version is a native crash, Fatal signal 11 (SIGSEGV), on 16KB devices. The first is a static check; the second is what users hit when the static check never ran.

The Console message appears when Play's analysis finds at least one .so in your bundle with 4KB ELF alignment. Your JavaScript never executes; the artifact is simply refused.

The runtime signature looks like this in logcat on a Pixel 8 or newer running a 16KB build of Android 15:

TEXT
F/libc: Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7a1c4000
  backtrace:
    #01 pc 00000000000a4xxx  /apex/.../libdl.so (dlopen+...)
    #02 pc ...               base.apk!libworklets.so (offset ...)

If your app shipped before the deadlines, crash reports with this shape in Play Vitals on 16KB devices have the same root cause as the upload rejection. Fix one and you fix both.

How do I find exactly which .so files are misaligned?

Three ways, in order of speed: a command-line ELF check you can paste right now, APK Analyzer in Android Studio, and lint in Android Studio 2025.1.2+, which now flags non-compliant native libraries at build time. The command-line check is the one you will keep, because it runs in CI.

Terminal output of an ELF alignment check flagging 4KB-aligned .so files inside a React Native APK that Google Play rejects
Terminal output of an ELF alignment check flagging 4KB-aligned .so files inside a React Native APK that Google Play rejects

Here is the script. It unpacks your release APK and prints the LOAD alignment of every arm64 library:

BASH
#!/bin/bash
# check_16kb.sh <path-to-apk>
APK="$1"
TMP="$(mktemp -d)"
unzip -q "$APK" "lib/arm64-v8a/*" -d "$TMP"

for SO in "$TMP"/lib/arm64-v8a/*.so; do
  ALIGN="$(objdump -p "$SO" | grep LOAD | awk '{ print $NF }' | head -n1)"
  if [ "$ALIGN" = "2**14" ] || [ "$ALIGN" = "2**16" ]; then
    echo "OK   $ALIGN  $(basename "$SO")"
  else
    echo "BAD  $ALIGN  $(basename "$SO")"
  fi
done
rm -rf "$TMP"

212 means 4096-byte alignment and fails. 214 (16384) or 216 passes. Mapping a bad file back to its npm package is usually obvious from the name: libreanimated.so is react-native-reanimated, librnskia.so is Skia, and so on. Also check zip-level alignment of uncompressed libraries with zipalign -c -P 16 -v 4 app-release.apk; AGP 8.7.0 handles this part automatically, older versions may not.

In Android Studio, open Build > Analyze APK and expand lib/arm64-v8a; versions 2025.1.2 and later show alignment per file and raise a lint error during assembly, so a misaligned library now fails loudly on your machine instead of silently at upload.

What is the fix, in order?

Toolchain first, dependencies second, rebuild last. The order matters because upgrading React Native and AGP often fixes libraries that are compiled from source during your build, shrinking the list of packages you actually need to touch.

  1. Upgrade React Native to 0.77 or newer. Core prebuilt binaries (Hermes and the React Native runtime) have shipped 16KB-aligned since the January 2025 release; the core-library history is tracked in facebook/react-native issue #52594. Use the Upgrade Helper diff, not a manual bump.

  2. Set AGP to 8.5.1 minimum, 8.7.0 recommended. 8.5.1 is the floor for correct 16KB packaging; 8.7.0 handles 16KB zip alignment for uncompressed native libs automatically.

  3. Move to NDK r28. r28 compiles everything with 16KB max page size by default. If you are stuck on r27 you must pass -Wl,-z,max-page-size=16384 to the linker for every target, which is easy to get wrong; r28 removes the foot-gun.

  4. Update the third-party libraries your scan flagged. See the table below.

  5. Rebuild clean. Run ./gradlew clean, then delete android/app/build and node_modules before the release build. The rebuild matters more than the code: two of my "failures" turned out to be stale .so files served from Gradle caches after the versions were already correct.


GROOVY
// android/build.gradle
buildscript {
    ext {
        ndkVersion = "28.0.13004108"
    }
    dependencies {
        classpath("com.android.tools.build:gradle:8.7.0")
    }
}

Commonly failing libraries and the versions that fixed them for me, verified as of June 2026 (always re-run the alignment script after bumping; maintainers occasionally regress prebuilt binaries):








DateRequirementStatus on June 10, 2026
November 1, 2025New apps and updates targeting Android 15+ must support 16KB pagesIn force
May 1, 2026ALL updates to existing apps must support 16KB pagesIn force
May 31, 2026Final Play Console extension expiryLapsed, nothing left to request
LibraryFirst 16KB-safe version
@shopify/react-native-skia>= 2.0.6
react-native-mmkv>= 3.0.2
react-native-reanimated>= 3.16.0
realm>= 20.1.0
@op-engineering/op-sqlite>= 9.3.0
react-native-vision-camera>= 4.6.1

90% of 16KB failures trace to two or three stale native dependencies. This is a half-day fix, not a sprint.

That line is the most useful thing I can tell you. Teams see a Play rejection that mentions native libraries and assume they need a native specialist for a month. In the engagements I have run through my mobile development practice , the work was almost always version bumps plus a disciplined clean rebuild.

What if a failing dependency is unmaintained?

Three options, in rising order of effort: patch the package so it rebuilds with your modern toolchain (2 to 4 hours), fork and recompile (half a day to a day), or replace it (anywhere from 3 hours to a week, depending on API surface).

patch-package works when the library ships C++ source and compiles during your build. Often the only problem is a build.gradle inside node_modules pinning an old NDK or stale externalNativeBuild flags. Edit it, confirm the alignment script passes, persist the change with npx patch-package .

Fork and fix is for libraries that ship prebuilt .so binaries. Patching Gradle does nothing because the binary was compiled on the maintainer's machine years ago. Clone the repo, bump its NDK to r28, rebuild the binaries, point your package.json at the fork. Budget a full day if the project's build setup is crusty.

Replace is sometimes fastest. I swapped an abandoned SQLite wrapper for op-sqlite in about 3 hours including data-layer tests, and that app got faster as a side effect. Audit your heaviest native modules first; things like the on-device AI integrations I wrote about bundle the largest binaries and hurt the most when abandoned.

Most of the app rescue work I take on starts exactly here: a blocked release, a dependency nobody has touched since 2023, and a team that needs the update out this week.

How do I verify the fix before I ship?

Two gates: run the alignment script in CI against the actual release artifact, and smoke-test on a 16KB emulator image. Only then upload to the internal testing track, where Play runs the same static check you just ran locally.

The CI step, as a GitHub Actions fragment:

YAML
- name: Verify 16KB ELF alignment
  run: |
    ./gradlew :app:assembleRelease
    ./scripts/check_16kb.sh app/build/outputs/apk/release/app-release.apk | tee align.txt
    ! grep -q '^BAD' align.txt

For the runtime check, install the Android 15.0 16KB Page Size** system image (API 35) from the SDK Manager, boot it, and confirm the kernel really is 16KB:

BASH
adb shell getconf PAGE_SIZE
# 16384

Then exercise every screen that touches native code: database reads, camera, animations, file storage. A crash here is the exact crash your Pixel 8 users would see, surfaced before review instead of after.

For what it is worth, here are my honest numbers across four client apps fixed between November 2025 and last month: one fix took 90 minutes (a single stale Skia version), two took about half a day each, and the worst took a day and a half because of the abandoned SQLite wrapper. None required changing a line of application code.

Key takeaways

  • The runway is gone: all Play updates require 16KB support since May 1, 2026, and the extension option expired May 31, 2026.

  • The toolchain floor is React Native 0.77+, AGP 8.5.1+ (8.7.0 recommended), and NDK r28.

  • Diagnose with the objdump alignment script or APK Analyzer; Android Studio 2025.1.2+ lint flags offenders at build time.

  • Most failures come from two or three stale native dependencies; bump them, then do a genuinely clean rebuild.

  • Verify with the alignment script in CI plus a smoke test on the 16KB emulator image before resubmitting.

FAQ

Why is my React Native app update being rejected by Google Play?

At least one `.so` file in your app bundle is aligned for 4KB memory pages. Since May 1, 2026, Google Play rejects every update containing such libraries, and the extension option expired May 31, 2026. Upgrade to React Native 0.77+, AGP 8.5.1+, NDK r28, and bump the flagged native dependencies.

How do I check which libraries don't support 16KB page sizes?

Unzip your release APK and run `objdump -p` on each `.so` in `lib/arm64-v8a`, checking the LOAD alignment: `2**12` fails, `2**14` or higher passes. APK Analyzer shows the same data visually, and Android Studio 2025.1.2+ lint flags non-compliant libraries during the build itself.

Do Expo apps support Google Play's 16KB page size requirement?

Yes, recent ones. Expo SDK 53 and newer produce 16KB-compliant builds by default because they ship on React Native 0.79+. Custom native modules in your config plugins still need auditing, which is one more reason I push teams toward [development builds instead of Expo Go](/article/expo-go-not-on-app-store-development-builds) for anything production-bound.

Working on something like this?

I build web apps, AI features, and mobile products for clients. If this article matches a problem you have, tell me about it.

Start a conversation
HS

Malik Hamza Shabbir · Full-Stack & AI Engineer

I build full-stack and AI products solo: a reputation SaaS in production, RAG pipelines, and React Native apps. I write from what I ship, not from documentation summaries.

Related articles