Quick Answer
Google Play requires apps targeting Android 15 (API level 35) or higher to support 16 KB memory page sizes on 64-bit devices, and from February 1, 2027 you will not be able to release updates that do not. An app written only in Java or Kotlin, including all of its libraries and SDKs, already complies. An app that packages native .so libraries fails until every one of them is rebuilt or replaced - preferably with Android Gradle Plugin 8.5.1+ and NDK r28+ - and the build passes two separate checks: every ELF LOAD segment aligned to at least 2**14, and the app bundle reporting PAGE_ALIGNMENT_16K. Upgrading your framework is not proof; the artifact is. If clearing this warning has stalled a closed test you were mid-way through, PrimeTestLab keeps the tester side running while you rebuild.
The warning is short, it names a filename at most, and it arrives after you already thought the build was finished. That is why the same three wrong turns keep happening: developers trust a deadline that moved, upgrade a framework and assume the job is done, or check one local APK and never look at the bundle Google actually builds from. This post is organised the way the problem actually resolves - identify, attribute, repair, prove - and everything on it is current as of August 5, 2026, checked against Google's page-size guide the same day that page was last updated. Where the evidence is a maintainer's issue tracker rather than an official release note, the page says so on the card instead of rounding it up to a fact.
The Alignment Lab
Twelve instruments built for this one error. Nothing here needs an account, an upload, or a network request - every tool runs in your browser against values you type in.
Table of contents
Fix It in Three Steps
Every genuine fix for this error is the same three moves in the same order: identify the native library that is not aligned, update the dependency that owns it, then verify the artifact you are about to upload. Skipping straight to step two is why so many developers upgrade a framework, rebuild, and watch the warning come back unchanged.
The requirement itself is narrow. Google's page-size guide says apps targeting Android 15 (API level 35) or higher must support 16 KB memory page sizes on 64-bit devices, and that from February 1, 2027 you will not be able to release updates that do not. It applies to native code only. If your app and every library and SDK inside it are pure Java or Kotlin, Google states that your app already supports 16 KB devices. The trouble is that most developers who see this warning believe they are in that category and are not.
Identify the failing .so
Open your release APK in Android Studio through Build > Analyze APK..., expand lib/arm64-v8a and lib/x86_64, and read the Alignment column. Write down every filename it flags. Those filenames are the only reliable search keys you have.
Update whatever owns it
A binary you compiled is fixed by your toolchain: AGP 8.5.1 or later with NDK r28 or later. A binary that arrived inside a plugin, SDK, engine or AAR can only be fixed by whoever built it, so the action is to upgrade, replace or request a rebuilt artifact from that package.
Find your framework's shortest pathVerify the artifact, not the upgrade
Two independent checks must both pass. Every ELF LOAD segment must be aligned to 2**14 or greater, and bundletool must report PAGE_ALIGNMENT_16K for the release bundle. Passing one proves nothing about the other.
The whole decision, on one screen
Before you change a single dependency version, walk this. It takes about two minutes and it is the difference between fixing the right thing and upgrading eleven packages that were never the problem.
Does the release APK contain a lib folder with .so files?
Already compliant
No native code in the APK. Google states a Java or Kotlin only app, including its libraries and SDKs, already supports 16 KB devices. Still worth one test run, and worth confirming you inspected the same build you uploaded.
Does APK Analyzer or check_elf_alignment.sh name an unaligned library?
Attribute, then upgrade
Find which framework, plugin, SDK or engine supplies that exact filename and update that package. Your own NDK cannot rewrite someone else's prebuilt binary.
What does bundletool dump config report for the release bundle?
PAGE_ALIGNMENT_4K
The libraries are fine but the packaging is not. Move to AGP 8.5.1 or later and rebuild, or apply the legacy packaging workaround if you cannot upgrade.
PAGE_ALIGNMENT_16K
Packaging is correct. Now test the Play generated APKs on a real 16 KB environment and audit any runtime code that assumes a fixed page size.
The trap in one line
A local APK that passes every alignment check does not prove the bundle you uploaded is correct. Google warns specifically that Android Gradle Plugin 8.3 through 8.5 can produce a bundle whose Play built APKs are not properly ZIP aligned, even when the APK on your machine looks perfect. That mismatch is the single most common reason the warning survives a "successful" fix.
What the Play Console Warning Actually Means
Google's documented consequence is precise: from February 1, 2027 you will not be able to release updates that target Android 15 (API level 35) or higher without 16 KB support. It is a release block on updates, not a statement that a published app is removed from the store on that date. Until then most developers see a compatibility warning, not a hard upload rejection.
The wording matters because the panic version of this story travels faster than the accurate one. Read the strings Google actually shows, and the scope becomes narrow and manageable.
App must support 16 KB memory page sizes
Reconstructed from Google's own Play Console screenshot on the page-size guide. Your Console layout and available buttons may differ by account.
Two readings of that card are commonly wrong. First, "Action by Feb 1, 2027" is not a countdown to deletion; Google's own text on the same page describes the outcome as being unable to release those updates. Second, the Extension granted string appears in Google's screenshot, but that does not establish that an extension request flow is currently open to you. Treat an extension as real only if you can see the option inside your own Play Console.
Which deadline did you actually read?
Three dates are circulating and only one is live. Pick whichever one you saw and this resolves its status against Google's current page, which was last updated on August 5, 2026.
Instrument 01
Deadline resolver
Google has moved this deadline more than once. Before you make a release plan around February 1, 2027, open the page-size guide yourself and check its "Last updated" stamp at the bottom. That one habit is worth more than any date printed in an article, including this one.
Does the 16 KB Requirement Affect My App?
Your framework does not decide this. The contents of your generated APK do. If there are .so files under lib, you are in scope regardless of whether you have ever opened a C++ file, and if there are none, Google's own guidance says you already support 16 KB devices.
Pure Java or Kotlin apps
Google is unambiguous here: if your app and all of its libraries and SDKs use only Java or Kotlin, your app already supports 16 KB devices. Google still recommends testing in a 16 KB environment to catch unexpected regressions, which costs you one emulator run.
The catch is the phrase "and all of its libraries and SDKs." A single database, analytics, crash reporting, media, maps, machine learning or security dependency can add native binaries to a project whose own source contains nothing but Kotlin. "I did not write C++" is not evidence. The lib folder is.
Flutter, React Native, Unity, Kivy and no-code builders
These stacks ship native runtimes, engine binaries and plugin libraries by design, so they are almost always in scope. Google explicitly names third-party app builders that use native libraries as a way an app can be affected even when its author never wrote C or C++. What varies is not whether you have native code but which package supplied the piece that is failing, which is why attributing the filename comes before any upgrade.
How to check, exactly
Open the release APK, expand lib, and look at the ABI folders inside it, normally arm64-v8a and x86_64. Any shared object files present means your app uses native code. No .so files and no lib folder means this APK does not use native code at all. The Alignment column in the analyzer displays warning messages for the files that have alignment problems, which is the fastest way to go from "something is wrong" to a filename.
Instrument 02
Affected triage
01 What does your app currently target?
02 Open the release APK in APK Analyzer. Is there a lib folder?
03 Which describes the app best?
04 Have you run bundletool dump config on the release bundle?
Why a 4 KB Binary Fails on a 16 KB Device
A memory page is the smallest block the kernel maps at once. Android has historically used 4 KB pages; Android 15 added support for devices configured with 16 KB pages. A native library records the alignment its segments were linked for, and if that value is smaller than the device's page size, the loader cannot place the segment on a page boundary.
That is the whole mechanism, and it explains the one number you will keep seeing. Alignment is expressed as a power of two: 2**12 is 4096 bytes, 2**14 is 16384 bytes. Google's rule is that each LOAD segment in a native library must be aligned to 2**14 or greater. A library built at 2**14 works on both 4 KB and 16 KB devices, because 16384 is a clean multiple of 4096. A library built at 2**12 only works on the smaller page size. That asymmetry is why the fix is always "raise the alignment" and never "detect the device."
Instrument 03
Page visualiser
Pick the alignment your library reports and see where its segments can start on a device using 16 KB pages.
Passes
There is a second, entirely separate constraint that lives outside the library. Uncompressed native libraries stored inside an APK must also sit on a 16 KB boundary within the ZIP archive itself. That is a packaging property, checked with zipalign and configured by your build plugin, and it can be wrong while every library inside is perfectly aligned. Keeping those two ideas apart is the single most useful thing you can carry out of this section.
Reading the numbers
When you see 2**14 in llvm-objdump output, that is a pass. 2**13 or 2**12 is a fail. There is no partial credit and no "close enough" - one unaligned LOAD segment in one library in one ABI is enough to keep the warning on your account.
The Shortest Fix for Each Framework
Framework readiness and app compliance are two different things. React Native 0.77 and the supported Unity versions are real, documented baselines. Flutter has no verifiable universal minimum. In every case the upgrade fixes the framework's own binaries and leaves every third-party plugin exactly as noncompliant as it was.
Instrument 04
Framework finder
What can still fail after this
Every baseline in one table
| Framework | Documented baseline | Shortest action | Confidence |
|---|---|---|---|
| Flutter | No verified universal minimum; 3.38 is the documented preparation milestone (default NDK r28) | Current stable Flutter, update native plugins, clean, rebuild, inspect every library | PARTIAL |
| React Native | 0.77 | Supported upgrade path, then update native modules and vendor SDKs | VERIFIED |
| Unity 6.1 line | 6000.1 or newer | Upgrade editor, update packages and plugins, rebuild | VERIFIED |
| Unity 6 LTS | 6000.0.38f1 or newer | Same as above | VERIFIED |
| Unity 2022 LTS | 2022.3.56f1 or newer | Same as above | VERIFIED |
| Unity 2021 | 2021.3.48f1 or newer, extended LTS eligibility required | Upgrade if entitled, otherwise migrate to a supported editor | VERIFIED |
| Unity Burst | 1.8.21 or newer | Upgrade Burst when lib_burst_generated.so is named |
VERIFIED |
| Native Android | NDK r28+ with AGP 8.5.1+ | Recompile owned code, update every prebuilt dependency | VERIFIED |
| Pinned to older NDK | r27 or lower with both linker options | Add max-page-size and common-page-size, rebuild all libraries |
WORKS, NOT PREFERRED |
| Kivy or Python builder | No universal version verified | Update builder and recipes, escalate the exact filename upstream | VENDOR DEPENDENT |
| No-code builder | No universal version verified | Regenerate on the vendor's compliant build stack, send them the filename | VENDOR DEPENDENT |
Confidence labels carry the same meaning everywhere on this page. VERIFIED means a current primary source states it directly. PARTIAL means a reliable source supports the core claim but not every implementation detail. REPORTED means the evidence is a maintainer's issue tracker or developer reports rather than an official release note.
Find the Exact Library Causing the Error
The filename is the whole investigation. Once you know that libfoo.so is the failing binary, the question stops being "how do I fix 16 KB support" and becomes "which package ships libfoo.so, and does a newer version exist". That second question has an answer; the first one does not.
Start in APK Analyzer
Open Build > Analyze APK..., load the release APK, and expand lib. Inside you will see one folder per ABI, normally arm64-v8a and x86_64. The Alignment column displays warning messages against files that have alignment problems. Android Studio's own warnings and Lint will also highlight noncompliant native libraries, so you may see the same finding surfaced in more than one place.
Record every flagged filename before you touch a single version number. Check both ABI folders separately: it is entirely normal for arm64-v8a to pass while x86_64 fails, or the reverse, because they are different binaries built by potentially different pipelines.
Decode the command line output
If you would rather work in a terminal, Google ships check_elf_alignment.sh, which reports ALIGNED or UNALIGNED for an APK, and you can inspect a single library directly with llvm-objdump. Both need Android SDK Build-Tools 35.0.0 or higher. Paste whatever they print below and this will read it back to you.
Instrument 05
ELF decoder
Paste output from llvm-objdump -p file.so | grep LOAD, check_elf_alignment.sh or zipalign -c -P 16. Everything is parsed in your browser; nothing is uploaded anywhere.
Work out which dependency owns it
Play Console and APK Analyzer both give you a filename and no owner. Type it in below and this will tell you what is known about that binary, with the evidence quality attached, and give you the search commands with your filename already in place.
Instrument 06
Library owner lookup
./gradlew app:dependencies shows you the resolved dependency graph, which is how you find the transitive package that pulled in a library you never added yourself. It will not tell you directly which artifact contains a given .so, so pair it with unzipping the suspect AAR. These are practical diagnostic techniques rather than Google-mandated steps.
Verify the App Bundle, Not Only the Local APK
Your local APK and the APKs Google Play generates from your bundle are different artifacts. ELF alignment lives inside each library; ZIP alignment is a property of how the archive was packed; and the bundle carries a configuration telling Play which of those to use. All three can disagree, and only the last one decides what users install.
This is the mechanism behind the most frustrating version of the problem: the developer upgrades everything, inspects the local APK, sees clean output, uploads, and the warning is still there. Nothing they checked was wrong. They just never checked the thing Play evaluates.
What you inspected
app-release.apk on your machineBuilt directly by Gradle on your hardware, with your packaging behaviour. Passing zipalign here proves this file is packed correctly.
What Play evaluates
APKs generated from app-release.aabBuilt by Google from your bundle, using the alignment the bundle asks for. If the bundle says 4 KB, these are wrong no matter how clean your local APK was.
So run this against the bundle you are about to upload, every time:
bundletool dump config --bundle=app-release.aab | grep alignment
PAGE_ALIGNMENT_16K is the result you want. PAGE_ALIGNMENT_4K means the bundle is telling bundletool to package native libraries on 4 KB boundaries, so every APK Play builds from it will be wrong. Google warns specifically that Android Gradle Plugin 8.3 through 8.5 can produce exactly this mismatch: the local build looks aligned, and the app Play builds from the bundle will not install correctly on a 16 KB device. The preferred fix is moving to Android Gradle Plugin 8.5.1 or later.
Every command, with your own filenames in it
Type your filenames once. Every command below rewrites itself, and each tab shows the exact output that counts as a pass, so you are never guessing whether a result was good.
Instrument 07
Command lab
Do not stop at "APK Analyzer says aligned"
A passing APK inspection is one of four checks, not the finish line. Confirm the ELF LOAD alignment, the APK ZIP alignment, the bundle configuration, and the runtime behaviour of the artifact Play actually generates. Any one of those failing is enough to keep the warning on your account after a build you believed was fixed.
AGP, NDK and the Packaging Trap
Two versions carry most of the weight. NDK r28 or higher compiles native code 16 KB aligned by default, and Android Gradle Plugin 8.5.1 or higher packages uncompressed native libraries on 16 KB ZIP boundaries correctly. Neither one can repair a precompiled binary that arrived inside a dependency.
The dangerous middle ground is Android Gradle Plugin 8.3 through 8.5. In that range a local build can look completely correct while bundletool does not ZIP align the APKs it produces from your bundle for Play, and Google's wording is blunt about the outcome: the app built from that bundle will not install properly. If you are on 8.5.0 and your local APK passes every check you can think of, this is the first thing to rule out.
Instrument 08
Toolchain checker
Build settings reference
| Situation | Setting | Notes |
|---|---|---|
| Preferred NDK | r28 or higher |
Produces 16 KB aligned native output by default |
| Preferred AGP | 8.5.1 or higher |
Handles uncompressed native libraries on 16 KB ZIP boundaries |
| NDK r27 or lower | -Wl,-z,max-page-size=16384 |
Required linker option on every native target |
| NDK r27 or lower | -Wl,-z,common-page-size=16384 |
Use together with the maximum page size option |
ndk-build |
LOCAL_LDFLAGS += ... |
Apply both options to each native target |
| CMake | target_link_options(...) |
Apply both options to each relevant target |
| Cannot upgrade AGP | jniLibs.useLegacyPackaging = true |
Compresses native libraries; increases installed disk use |
| AGP 8.0 or lower | android.bundle.enableUncompressedNativeLibs=false |
Additional legacy property alongside the option above |
| Runtime code | getpagesize() or sysconf(_SC_PAGESIZE) |
Replace hard-coded 4096 and fixed PAGE_SIZE assumptions |
The part that packaging cannot fix
If your own C or C++ assumes a page size, no build flag saves you. Remove hard-coded 4096 values and any reliance on a fixed PAGE_SIZE constant, query the real value at runtime with getpagesize() or sysconf(_SC_PAGESIZE), and review every mmap() call along with any argument you are page-aligning by hand. This is the class of failure where an app installs cleanly on a 16 KB device, passes the bundle checks, and then crashes the first time it touches memory mapping.
Order of operations
Fix the compiler side before the packaging side. If you apply the legacy packaging workaround first, your APK will start passing zipalign while the libraries inside it are still built for 4 KB pages, and you will have hidden the real problem behind a green result.
Test on a Real 16 KB Environment
One command decides whether your test means anything: adb shell getconf PAGE_SIZE must return 16384. Run it before every session. An emulator that quietly booted in 4 KB mode will let a broken build pass everything you throw at it.
You have three practical routes and two specialist ones. Pick whichever you can actually get to today; there is no quality difference between them for the purpose of catching page-size failures.
Instrument 09
Test environment picker
Limitation
Then, every single time, before any test
adb shell getconf PAGE_SIZE
Do not continue unless the output is 16384.
What to actually exercise
Once the environment is confirmed, the useful test pass is not "does it launch". Native failures cluster in the features that touch native code, so drive those deliberately: cold launch, navigation through the app, camera, database reads and writes, media playback and recording, authentication, background work, any machine learning or augmented reality feature, every native plugin surface, and anything in your own code that uses memory mapping. If a feature is powered by one of the libraries you just upgraded, that feature is the test.
Backcompat mode is not a pass
Android can run some 4 KB aligned apps on a 16 KB device through a compatibility path, and you may see a warning at first launch when it does. Google still recommends proper 16 KB alignment for best reliability and stability. An app that only runs because backcompat intervened is not a fixed app, and shipping on that basis means the real failure is still ahead of you.
Why the Warning Survives an Upgrade
Almost every "I already fixed it" case is one of thirteen specific situations, and eleven of them are provable from the artifact in front of you. Pick the symptom that matches and you will usually know the cause before you finish reading it.
Instrument 10
Stuck-warning triage
Two of those deserve a caveat rather than a confident answer. No primary source establishes how long Google Play takes to reassess an uploaded bundle, so if your warning persists immediately after an upload, the honest move is to confirm the new version code appears under your latest releases and app bundles and then check again later, rather than to trust any specific number you read about processing times. And an app that runs only because backcompat mode intervened has not been fixed, it has been accommodated.
Third-Party Libraries That Keep Coming Up
These are reported examples, not a ranking of how common each one is, and not a promise that a given version will fix your build. A package can add, remove or replace native artifacts in any release. The final authority is always the binary sitting inside your own release bundle.
Use this as a starting point when a filename looks familiar, then verify against that project's current releases and open issues. Where the evidence is a maintainer's issue tracker rather than a release note, the card says so.
Instrument 11
Reported library index
libobjectbox-jni.so
Older Android native libraries failed in a 16 KB environment. A specific fixed version was not confirmed strongly enough here to publish. Check ObjectBox's current release notes for the version that added 16 KB support, then confirm the binary inside your built APK rather than trusting the version alone.
bundled Android library
ObjectBox's Dart SDK bundles its own Android library. A specific fixed version was not confirmed strongly enough here to publish. Check ObjectBox's current release notes, then verify the artifact your build actually resolves.
libsqlite3.so
An older 3.43.0 dependency appeared in affected Flutter and AWS Amplify packaging. Issue evidence identifies 3.46.1+1 as the version that added 16 KiB support. Check the resolved dependency version, not only the one you declared, because a framework package can pin an older one.
sqlcipher-android
The older android-database-sqlcipher package is deprecated upstream in favor of the maintained sqlcipher-android package. No specific version was confirmed strongly enough here to publish as a fixed minimum, so migrate to the current maintained package and validate every ABI in the built app rather than trusting a version number.
media processing binaries
The original FFmpegKit repository was retired, and no universally safe compliant release was established. Fork quality varies. Identify exactly which fork your build resolves, inspect its ABI artifacts directly, and weigh maintenance and provenance before adopting one as your fix.
Realm and JNI binaries
Reports conflict. Version 20.1.0 was flagged, and a later report said 20.2.0 repaired one Realm binary while another JNI binary remained a problem. No single safe version can be responsibly named, so upgrade and then check every library Realm contributes individually.
libmediapipe_tasks_vision_jni.so
Reported at 2**12 alignment. No fixed release was established in the issue consulted, so treat compatibility as version specific: check current release notes, upgrade, and verify the binary in your own build.
OpenCV Android artifact
Alignment was reported against an OpenCV 5.0.0 Android artifact. The repository issue references a CI fix, but no specific released artifact was safely established. Download the exact AAR you depend on, unzip it, and inspect the libraries yourself.
lib_burst_generated.so
Unity's own guidance is to update the Burst package to 1.8.21 or later when this file is flagged. This is the one entry in the index backed by official vendor documentation rather than issue reports.
libUnityARCore.so, libquack.so and others
Community reports name these among the binaries that survive an editor upgrade. There is no universal version to quote because each one belongs to a different package. Use the exact filename to decide which package to chase.
No entry matches that filter. That is normal: this index covers reported examples, not every library in the ecosystem. Use the library owner lookup and trace the file inside your own project.
Why this index is short: issue counts show which projects have vocal users, not which libraries are most often installed. Publishing a ranked list of "the most common offenders" would be inventing a statistic. What generalises instead is the method - take the filename, find the package, check that package's current releases, verify the binary in your build.
How This Relates to the August 31, 2026 API 36 Deadline
They are two independent Google Play requirements that meet in one place. Raising your target API level can expose the 16 KB warning, because the requirement applies to apps targeting Android 15 (API level 35) or higher. It does not create the misalignment and it cannot repair it.
Google Play requires new apps and app updates to target Android 16 (API level 36) from August 31, 2026, with an extension available to November 1, 2026. That is a manifest and behaviour change. The 16 KB rule is a binary compatibility change. A developer who bumps targetSdk on a Monday and sees a 16 KB warning on Tuesday has not broken anything: the native libraries were already built for 4 KB pages, and the higher target level simply brought the app into scope of a check that was always going to apply.
Requirement A
Target API 36- Date August 31, 2026, extension to November 1, 2026
- Scope New apps and app updates
- Lives in Your manifest and build configuration
- Fixed by Raising the target level and handling Android 16 behaviour changes
Requirement B
16 KB page size support- Date February 1, 2027
- Scope Apps targeting API 35+ on 64-bit devices
- Lives in The native binaries inside your bundle
- Fixed by Rebuilding or replacing every unaligned library
Practically, treat them as one migration with two proofs. You will be raising the target level anyway, so schedule the native library audit into the same release rather than discovering it during the API 36 scramble. For the full set of form factor levels, exceptions and extension mechanics on the target API rule, see our Google Play target API 36 deadline post, and for the whole sequence from account to production our 2026 publishing requirements post.
The Pre-Upload Release Gate
Eleven checks, each with a specific piece of passing evidence. Work through them before you upload rather than after Play tells you something is wrong, and you convert an unbounded debugging session into a finite list.
Instrument 12
Release gate
0 of 11 cleared
Nothing proven yet. Start with the build you actually intend to upload, not the last one you happened to have open.
Your progress is stored in this browser only. Nothing is sent anywhere, and clearing your browser data clears it.
Clearing all eleven gates proves technical alignment against the checks cited on this page. It is not a promise of approval. Google Play can still raise unrelated policy, content or quality issues on the same upload, and no checklist anywhere can speak for those.
Where This Collides With Closed Testing
Nothing on this page changes your tester requirement, and nothing about your testers changes your build. The two problems collide on one axis only: time. A 14-day closed test runs on a clock you cannot pause, and a native library investigation runs on a clock nobody can predict.
The sequence that hurts goes like this. A personal developer account starts a closed test, the 14-day continuous opt-in window begins, and somewhere in the middle of it a target level bump surfaces a 16 KB warning. Now the developer is rebuilding native dependencies while a tester group has to stay intact around them. Uploading a new build to the track is fine, and Google encourages developers to keep updating during a test. What breaks the run is the tester side going quiet.
That is the part PrimeTestLab holds steady. We supply 12 real testers on real devices spanning Android 7 to 17, opted in and held for the full 14 days, so your rebuild happens against a stable test rather than a collapsing one. Testing starts in 4-6 hours, and we have run this across 7,400+ apps in 120+ countries with a 99.9% success rate.
Recruiting testers yourself versus a managed run
| Google's requirement | Recruiting it yourself | Managed run |
|---|---|---|
| At least 12 opted-in testers | Find, brief and chase real people, then hope none of them opt out | 12 supplied and held for the whole window |
| 14 continuous days | One tester leaving mid-run breaks the continuous window | The group is monitored so the window stays intact |
| Real devices, real humans | Emulators and inactive accounts are the usual shortcut, and the usual reason a run fails | Real devices across Android 7 to 17 |
| Time to first opt-in | Days, depending on who answers you | Testing starts in 4-6 hours |
| Cost | Your time, during the week you are already rebuilding libraries | From $19.99 |
| Rebuilding mid-test | Every new upload is another round of asking people to update | Push new builds freely; the group stays opted in |
To be direct about the boundary: we do not rebuild your native libraries and this post is not a sales pitch for doing so. The 16 KB work is yours, and everything above this section is written to make it as short as possible. What we take off your plate is the tester requirement running alongside it, so the two problems stop competing for the same fortnight.
Sequencing tip
If you have not started the closed test yet and you already know you have native libraries, get the tester window running first and do the alignment work inside it. Google's qualifying period is measured around tester opt-in continuity rather than one frozen build, and it encourages developers to keep updating during a test, so the two timelines can overlap instead of stacking. Keep the same track and tester group while you do it. That is often a full week saved.
Frequently Asked Questions
Is Google Play rejecting 16 KB incompatible apps right now?
Google's current documentation says that beginning February 1, 2027 you will not be able to release updates that target Android 15 (API level 35) or higher without 16 KB support on 64-bit devices. Before that date most developers see a compatibility warning in Play Console rather than a hard block. The documented consequence on the cited Google page is an inability to release noncompliant updates, not automatic removal of an app that is already published.
Why does Google say February 1, 2027 when other articles say November 1, 2025?
November 1, 2025 was Google's original announced deadline and May 31, 2026 was a later historical extension date. As of August 5, 2026 Google's current Android Developers page and the current Play Console warning screenshot both show February 1, 2027, so the newer primary source controls. Many blog posts and AI answers still quote the older dates because they were written before the change.
I never wrote C++. Why is my app affected?
A framework, SDK, plugin, game engine, database, media component or app builder can add native .so files even when your own source is Dart, JavaScript, Python, Java or Kotlin. Google's guidance explicitly includes apps that use NDK libraries indirectly through a dependency. Open the APK in Android Studio with Build then Analyze APK; any .so file under lib means the packaged app uses native code.
Does a pure Kotlin app need any changes?
According to Google, an app that uses only Java or Kotlin, including all of its libraries and SDKs, already supports 16 KB devices. Google still recommends testing in a 16 KB environment for unexpected regressions. Verify that the actual release APK has no lib directory before calling your app pure Kotlin, because a single analytics or database dependency can add one.
What Flutter version fixes the 16 KB page size warning?
No official source establishes one Flutter version that guarantees every Flutter app and plugin is compliant. Flutter 3.27's release notes are narrower than they look, covering 16 KB support for plugin_ffi templates specifically rather than the whole engine. Flutter 3.38 is the strongest documented milestone: Flutter explicitly positioned upgrading to it as preparation for Play's 16 KB requirement and switched the default NDK to r28. The safest action is to move to the current stable Flutter release, update every native plugin, rebuild the release bundle, and inspect each .so file that comes out.
What React Native version supports 16 KB pages?
React Native 0.77 is the clear official baseline. Its release announcement states that React Native is ready to fully support 16 KB page sizes. Native community modules, local C++ code and third-party SDKs can still ship incompatible binaries, so upgrade through the supported React Native or Expo migration path and then inspect the generated APK.
Which Unity version do I need for 16 KB page size support?
Unity lists 6000.1 or newer, 6000.0.38f1 or newer, 2022.3.56f1 or newer, and 2021.3.48f1 or newer under extended LTS for eligible Enterprise or Industry customers. Update your native plugins as well, and move Burst to 1.8.21 or later if Play Console names lib_burst_generated.so. A supported editor version is necessary but not sufficient, because third-party plugins ship their own binaries.
How do I find the exact .so file that is failing?
Open the APK through Build then Analyze APK in Android Studio, expand lib/arm64-v8a and lib/x86_64, and read the Alignment column, which displays warnings for files with alignment problems. For command line confirmation run Google's check_elf_alignment.sh script against the APK, or inspect one library with llvm-objdump -p file.so piped to grep LOAD. Any LOAD alignment below 2**14 needs attention.
Why does my APK pass but my app bundle still fail?
ELF alignment inside a library and ZIP alignment inside the packaged artifact are two separate checks. Run bundletool dump config --bundle=app.aab and grep for alignment: PAGE_ALIGNMENT_16K passes while PAGE_ALIGNMENT_4K means generated APKs are still requested at 4 KB. Google specifically warns that Android Gradle Plugin 8.3 through 8.5 can look correct locally while the APKs Play builds from your bundle are not properly ZIP aligned, so move to 8.5.1 or later.
Is upgrading to NDK r28 enough to fix it?
No. NDK r28 and higher compile 16 KB aligned by default, but that only affects native code compiled during your build. It cannot rewrite a precompiled .so file that arrives inside a third-party AAR, plugin or game engine package. Every prebuilt native dependency must itself be updated, replaced or rebuilt and reimported.
How can I test 16 KB support without owning a supported phone?
Install one of Google's 16 KB Android Emulator system images through the SDK Manager, or book a supported device through Samsung Remote Test Lab. Whatever you use, confirm the environment first with adb shell getconf PAGE_SIZE; the output must be 16384 before the test means anything. Emulator success proves runtime behaviour, not packaging, so keep inspecting the release bundle too.
Does fixing 16 KB support reset or affect my closed testing run?
Google measures the qualifying period around at least 12 testers staying opted in continuously for 14 days, not around one frozen build, and it encourages developers to keep updating the build during a test. Google does not publish an explicit guarantee covering every build-replacement scenario, so the safest approach is to keep your tester group stable while you push a rebuilt 16 KB compliant bundle mid test. PrimeTestLab supplies 12 real testers on real devices from $19.99 and holds the group for the full 14 days.
Bottom Line
Summary
Google Play requires apps targeting Android 15 (API level 35) or higher to support 16 KB memory page sizes on 64-bit devices, and from February 1, 2027 noncompliant updates cannot be released. November 1, 2025 and May 31, 2026 are dead dates that still rank. Pure Java or Kotlin apps already comply. Everyone else works the same three steps: name the failing .so, update the package that owns it, and prove the artifact with two independent checks - every ELF LOAD segment at 2**14 or greater, and the bundle reporting PAGE_ALIGNMENT_16K. AGP 8.5.1+ with NDK r28+ is the safest default toolchain, and neither one can repair a binary someone else compiled. If this lands mid closed test, the tester side is the part you can hand off. See pricing plans →
Primary Sources
What on this page will go stale first
- The February 1, 2027 date. Google has moved this timeline more than once. Check the "Last updated" stamp at the bottom of the page-size guide before you plan a release around it.
- The Play Console strings. Console copy and navigation change independently of the policy pages, so the exact headings you see may differ from the ones reproduced here.
- Framework baselines. Flutter ships stable releases frequently, React Native support policy evolves, and Unity LTS eligibility changes. Confirm against the current release notes rather than a version printed in an article.
- The reported library index. Any package can add, replace or regress a native binary in any release. Always verify the artifact in your own bundle.
- Emulator image names. Images labelled experimental may be renamed or promoted, so the exact string in SDK Manager may not match.
Verified against Google's documentation on August 9, 2026. Reviewed monthly until at least one month after enforcement.