Skip to main content

Blog

Flutter, FFmpegKit and Android’s 16 KB Page Size Requirement

Why Flutter apps fail Google Play’s 16 KB page size check, how to find the native library at fault, and what to do when the dependency that broke it has been archived.

5 min read

If Google Play has told you your app “is not compatible with 16 KB page size devices”, or your app installs fine everywhere except the newest Android hardware, this is the problem. It is one of the few compliance issues that can block a release outright, and Flutter teams are disproportionately affected for a reason that is not obvious.

What the requirement actually is

Android 15 introduced support for devices using 16 KB memory pages instead of the traditional 4 KB. Since 1 November 2025, new apps and updates submitted to Google Play that target Android 15 or higher must support 16 KB page sizes. Native libraries built for 4 KB pages may fail to load on those devices — the app can refuse to install, fail to start, or crash once it touches the library.

If your app contains no native code at all, you are unaffected and nothing needs to change.

Why this hits Flutter apps

Dart is not the problem. Plugins are.

A Flutter app with media processing, machine learning, local databases, cryptography or video playback is shipping prebuilt .so files it did not compile. You inherit the alignment of every native library in your dependency tree, which means a one-line addition to pubspec.yaml two years ago can be what blocks your release today.

Find out which libraries are the problem

Do not guess. Get the list first.

  • Play Console flags affected releases in the App Bundle Explorer and pre-launch report — useful confirmation, but it will not always tell you which library is at fault.
  • Inspect the ELF headers. Unpack your APK or bundle and check each .so in lib/<abi>/. objdump -p libfoo.so and look at the first LOAD segment's align value: 2**14 is 16 KB and 2**16 is 64 KB — both fine. 2**12 is 4 KB, and that is your culprit.
  • Use Google's script. check_elf_alignment.sh walks the libraries for you and reports each one as aligned or not, which is far quicker than reading headers by hand.
  • Check the zip alignment too. zipalign -c -P 16 -v 4 app.apk verifies alignment of the archive, which is separate from the ELF alignment inside each library.

Work through the list and you will usually find the offenders are one or two media, ML or database plugins.

The fix, cheapest option first

1. Update your build tooling

Android Gradle Plugin 8.5.1 or later aligns uncompressed native libraries on 16 KB boundaries when it builds your bundle. Recent NDK releases produce 16 KB compatible libraries by default. For a surprising number of apps, updating AGP, Gradle and the NDK is the entire fix.

2. Update the plugins that ship native code

Most actively maintained packages shipped compatible builds well before the deadline. Update them, rebuild, and re-run the check. This resolves the majority of remaining cases.

3. Replace the plugin

If a package is abandoned, the honest answer is often to move to a maintained alternative — even when that means rewriting the integration. It is usually cheaper than owning a native build.

4. Compile it yourself

Only when the first three fail. Which brings us to the case that sent a lot of Flutter teams here.

The FFmpegKit problem

FFmpegKit was the default way to do serious audio and video processing in a Flutter app. Then it went away.

The maintainer announced its retirement in January 2025. Prebuilt package distribution ended in April 2025, the repository was archived in July 2026, and the Flutter package carries an unmaintained flag on pub.dev. So for anyone using it, step 2 above — update the dependency — simply does not exist. There is no newer compliant build to move to.

That leaves three realistic paths:

  • FFmpegKitNext, the continuation project from the original author. It is distributed as source rather than prebuilt packages, so you are building it yourself either way — but with a maintained toolkit rather than an archived one.
  • A commercial media SDK, if your needs map cleanly onto what one offers. Fastest to integrate, least flexible, and it has a price.
  • Build FFmpeg yourself with a toolchain that produces 16 KB aligned libraries.

We took the third path on Leklok, which uses native audio processing for voice modification. A custom FFmpegKit build with 16 KB page-size alignment kept the feature working and the Android release compliant, without rewriting the audio pipeline around a different SDK.

What building it yourself actually costs

Be clear-eyed before choosing this:

  • You need a working NDK cross-compilation setup per ABI, and the linker configured for a 16 KB maximum page size (max-page-size=16384).
  • You should compile only the codecs and filters you actually use. The default build is enormous, and trimming it is the difference between a sane APK and a bloated one.
  • It has to be reproducible in CI, or the knowledge lives on one laptop and expires when that person is busy.
  • You now own it. Every future NDK change, alignment rule or security patch is yours to track.

That is a real cost, and it is worth paying only when the feature is central to your product. For a voice-first social app, native audio processing is the product. For an app that crops a video once during onboarding, it is not — replace the plugin.

Avoiding the next one

This will not be the last platform requirement to arrive with a deadline. The teams that handled it in an afternoon had two things in place:

  • An inventory of native dependencies. Know which packages ship .so files and whether each is actively maintained, before a deadline makes it urgent.
  • A check in CI. Run the alignment check on every release build. A failed pipeline months before the deadline is cheap; a blocked release the week of launch is not.

If you are staring at a Play Console warning and an archived dependency, that is the kind of thing our mobile app development team untangles — and the sort of platform work we cover in our process rather than treating as a surprise.

Frequently asked questions

What is the Android 16 KB page size requirement?
Android 15 supports devices with 16 KB memory pages instead of 4 KB. Since 1 November 2025, new apps and updates on Google Play targeting Android 15 or higher must include native libraries that work on those devices, or the app may fail to install, fail to start, or crash.
Does the 16 KB requirement affect Flutter apps?
Only through plugins. Dart code is unaffected, but any plugin shipping prebuilt native libraries — media processing, machine learning, local databases, cryptography — brings its own alignment with it, and your build inherits it.
How do I check if my app is 16 KB compatible?
Inspect the first LOAD segment of each .so in lib/<abi>/: an align value of 2**14 or 2**16 is fine, 2**12 is not. Google's check_elf_alignment.sh automates it, and zipalign -c -P 16 verifies the archive alignment separately.
What replaced FFmpegKit?
FFmpegKitNext, from the original author, is the continuation project, distributed as source rather than prebuilt packages. The alternatives are a commercial media SDK or compiling FFmpeg yourself with a 16 KB aligned toolchain.
Can I just ignore the warning?
Not for long. It blocks new releases targeting Android 15 or higher on Google Play, and on 16 KB devices affected apps can fail to install or crash — so the choice is fixing it or not shipping updates.

Ready to scope your MVP? Get in touch or explore our portfolio, or grab the free MVP scoping checklist.

Ready to build something remarkable?

Book a free 20-minute scoping call. We'll review your idea, share relevant case studies, and outline a realistic timeline.

Reply within 24 hours · No commitment required