Flutter app crashes on Android (0.14.0) - Too many open files
Description
My flutter app crashes on Android devices after remaining idle for some time. This happens when I use Factory.rive riveFactor instead of Factory.flutter. I use the feathering features on Rive and it is disabled when I use Factory.flutter.
Steps To Reproduce
Steps to reproduce the behavior:
- Run the app on Android
- Load a rive file that has feathering enabled
- Wait a few seconds
- App will freeze and will be unusuable
Logs
E/flutter (29988): [ERROR:flutter/impeller/renderer/backend/vu
lkan/swapchain/khr/khr_swapchain_impl_vk.cc(483)] Break on
'ImpellerValidationBreak' to inspect point of failure: Could not present
queue: ErrorInitializationFailed
5
E/RiveNative(29988): (12291) EGL_BAD_ALLOC -
../../../../platform/android/rive_native_android.cpp:292
E/ProcessState(29988): readDriverFeatureFile: cannot open
/dev/binderfs/features/extended_error: Too many open files
E/GraphicBufferAllocator(29988): Failed to allocate (273 x 105) layerCount
1 format 1 usage 40000000000300: -129
E/BufferQueueProducer(29988):
[ImageReader-273x105f22m5-29988-36](id:752400000026,api:1,p:29988,c:29988)
dequeueBuffer: createGraphicBuffer failed
E/GraphicBufferAllocator(29988): Failed to allocate (273 x 105) layerCount
1 format 1 usage 40000000000300: -129
E/BufferQueueProducer(29988):
[ImageReader-273x105f22m5-29988-36](id:752400000026,api:1,p:29988,c:29988)
dequeueBuffer: createGraphicBuffer failed
E/RiveNative(29988): (12301) EGL_BAD_SURFACE -
../../../../platform/android/rive_native_android.cpp:292
5
E/RiveNative(29988): (12291) EGL_BAD_ALLOC -
../../../../platform/android/rive_native_android.cpp:292
E/flutter (29988): [ERROR:flutter/impeller/renderer/backend/vulkan/swapcha
in/khr/khr_swapchain_impl_vk.cc(208)] Break on 'ImpellerValidationBreak'
to inspect point of failure: Could not create swapchain:
ErrorNativeWindowInUseKHR
E/Surface (29988): freeAllBuffers: 1 buffers were freed while being
dequeued!
E/flutter (29988): [ERROR:flutter/impeller/renderer/backend/vulkan/swapcha
in/khr/khr_swapchain_vk.cc(73)] Break on 'ImpellerValidationBreak' to
inspect point of failure: Could not update swapchain.
2
E/flutter (29988):
[ERROR:flutter/shell/gpu/gpu_surface_vulkan_impeller.cc(95)] No surface
available.
Expected behavior
- It should not be crashing. The exact file and code works fine on iOS
Device & Versions (please complete the following information)
- Device: Google Pixel 9a
- OS: Android 16
- Flutter Version:
Flutter 3.29.3 • channel [user-branch] • unknown source
Framework • revision ea121f8859 (5 months ago) • 2025-04-11 19:10:07 +0000
Engine • revision cf56914b32
Tools • Dart 3.7.2 • DevTools 2.42.3
- Rive SDK version:
rive: ^0.14.0-dev.6
Additional context
This only happens on Android. It works fine on iOS.
This happens when I use
Factory.rive
Same issue
I also get a very similar crash, but before that my logs get spammed with
W/ImageReader_JNI( 7625): Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers.
I have a list of rive widgets on the screen and it happens nearly straight away. After a while it just crashes. If I change the factory to Rive.flutter, than it works.
I'm using 0.14.0-dev.8
I have exactly the same issue. It happens only on Android and freezes the whole app after a few minutes. At the same time, I have 5 Rive files rendered on the screen.
Testing device: Google Pixel 4 (Android 13) Rive Editor: Early Access 0.8.3562 rive_native: ^0.0.11 rive: ^0.14.0-dev.8
Flutter 3.35.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision d693b4b9db (2 weeks ago) • 2025-09-16 14:27:41 +0000
Engine • hash feee8ee8fb8b975dd9990f86d3bda11e6e75faf3 (revision c298091351) (16 days ago) • 2025-09-15 14:04:24.000Z
Tools • Dart 3.9.2 • DevTools 2.48.0
/Fence (15753): merge: sync_merge("ImageReader-168x168f22m6-157:2", 32718, -1) returned an error: Too many open files (-24)
E/LayerState(15753): ERROR(Too many open files, -24). Failed to call parcel output->write(*acquireFence)
E/LayerState(15753): ERROR(Too many open files, -24). Failed to call parcel output.writeParcelable(*bufferData)
E/SurfaceFlinger(15753): ERROR(Too many open files, -24). Failed to call parcel s.write(data)
W/Adreno-GSL(15753): <gsl_ldd_control:553>: ioctl fd 112 code 0xc0200933 (IOCTL_KGSL_TIMESTAMP_EVENT) failed: errno 24 Too many open files
W/Adreno-GSL(15753): <ioctl_kgsl_syncobj_create:4437>: (71, 1e, 85573) fail 24 Too many open files
W/Adreno-GSL(15753): <gsl_ldd_control:553>: ioctl fd 112 code 0xc0200933 (IOCTL_KGSL_TIMESTAMP_EVENT) failed: errno 24 Too many open files
W/Adreno-GSL(15753): <ioctl_kgsl_syncobj_create:4437>: (71, 1a, 32442) fail 24 Too many open files
E/flutter (15753): [ERROR:flutter/impeller/renderer/backend/vulkan/command_queue_vk.cc(67)] Break on 'ImpellerValidationBreak' to inspect point of failure: Failed to submit queue: ErrorInitializationFailed
E/flutter (15753): [ERROR:flutter/impeller/display_list/canvas.cc(2104)] Break on 'ImpellerValidationBreak' to inspect point of failure: Failed to submit command buffers
W/Adreno-GSL(15753): <gsl_syncobj_dup_fd:272>: 0xb40000713aad5c50 dup(15276) error 24 Too many open files
E/qdgralloc(15753): importBuffer: Unable to clone handle
E/GraphicBufferAllocator(15753): Failed to allocate (168 x 168) layerCount 1 format 1 usage 10000100: 5
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) dequeueBuffer: createGraphicBuffer failed
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) requestBuffer: slot 5 is not owned by the producer (state = FREE)
E/Surface (15753): dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) cancelBuffer: slot 5 is not owned by the producer (state = FREE)
I/Adreno (15753): DequeueBuffer: dequeueBuffer failed
E/qdgralloc(15753): importBuffer: Unable to clone handle
E/GraphicBufferAllocator(15753): Failed to allocate (168 x 168) layerCount 1 format 1 usage 10000100: 5
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) dequeueBuffer: createGraphicBuffer failed
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) requestBuffer: slot 5 is not owned by the producer (state = FREE)
E/Surface (15753): dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22
E/BufferQueueProducer(15753): [ImageReader-168x168f22m6-15753-3](id:3d8900000005,api:1,p:15753,c:15753) cancelBuffer: slot 5 is not owned by the producer (state = FREE)
I/Adreno (15753): DequeueBuffer: dequeueBuffer failed
E/RiveNative(15753): (12301) EGL_BAD_SURFACE - ../../../../platform/android/rive_native_android.cpp:292
I am seeing spam of below line when Rive animation goes out of the viewport. Doesn't crash though.
Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
I need to look into Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
But the latest release fixed a graphics memory issue, which very likely should solve the above crashes/issues.
Could you try 0.14.0-dev.11 and let us know.
If the latest does not solve the issue could you please provide a small sample project with steps to reproduce the issue.
I need to look into
Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffersBut the latest release fixed a graphics memory issue, which very likely should solve the above crashes/issues.
Could you try 0.14.0-dev.11 and let us know.
If the latest does not solve the issue could you please provide a small sample project with steps to reproduce the issue.
@HayesGordon , the issue seems to be happening. Here is minimal sample code using 0.14.0-dev.11 version of Rive. Let me know if you need the animation file as well or if this is enough to reproduce. When you scroll just enough that Rive animation goes out of the visible area, the logs flood with:
W/ImageReader_JNI(21977): Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
CODE:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late FileLoader _fileLoader;
@override
void initState() {
super.initState();
_fileLoader = FileLoader.fromAsset(
'rive/play_button_small.riv',
riveFactory: Factory.rive,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text("Flutter Demo Home Page"),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(width: double.infinity, height: 400, color: Colors.red),
RiveWidgetBuilder(
fileLoader: _fileLoader,
builder: (BuildContext context, RiveState state) {
if (state is RiveLoading) {
return CupertinoActivityIndicator();
} else if (state is RiveFailed) {
return Text('Error loading Rive file: ${state.error}');
} else if (state is RiveLoaded) {
return SizedBox(
height: 80,
child: RiveWidget(controller: state.controller),
);
}
return Container();
},
),
Container(width: double.infinity, height: 400, color: Colors.red),
Container(width: double.infinity, height: 800, color: Colors.blue),
Container(width: double.infinity, height: 400, color: Colors.red),
],
),
),
);
}
}
I need to look into
Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffersBut the latest release fixed a graphics memory issue, which very likely should solve the above crashes/issues. Could you try 0.14.0-dev.11 and let us know. If the latest does not solve the issue could you please provide a small sample project with steps to reproduce the issue.@HayesGordon , the issue seems to be happening. Here is minimal sample code using
0.14.0-dev.11version of Rive. Let me know if you need the animation file as well or if this is enough to reproduce. When you scroll just enough that Rive animation goes out of the visible area, the logs flood with:
W/ImageReader_JNI(21977): Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffersCODE:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:rive/rive.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { late FileLoader _fileLoader; @override void initState() { super.initState(); _fileLoader = FileLoader.fromAsset( 'rive/play_button_small.riv', riveFactory: Factory.rive, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text("Flutter Demo Home Page"), ), body: SingleChildScrollView( child: Column( children: [ Container(width: double.infinity, height: 400, color: Colors.red), RiveWidgetBuilder( fileLoader: _fileLoader, builder: (BuildContext context, RiveState state) { if (state is RiveLoading) { return CupertinoActivityIndicator(); } else if (state is RiveFailed) { return Text('Error loading Rive file: ${state.error}'); } else if (state is RiveLoaded) { return SizedBox( height: 80, child: RiveWidget(controller: state.controller), ); } return Container(); }, ), Container(width: double.infinity, height: 400, color: Colors.red), Container(width: double.infinity, height: 800, color: Colors.blue), Container(width: double.infinity, height: 400, color: Colors.red), ], ), ), ); } }
@nikorehnback just to confirm, is this a reproduction of the warning log you're seeing? Or does this reproduce one of the crashes mentioned above?
@nikorehnback just to confirm, is this a reproduction of the warning log you're seeing? Or does this reproduce one of the crashes mentioned above?
This reproduces the warning. No crash with this one. Also tried to add 10+ RiveWidgets, only more same message to logs, no crash with that either.
Yes, the same for me (the log spamming) , i have a list of 11 rive animations the play as get this as soon as I scroll the list with them into view, but not spotting any actual crashes
same issue. App doesn't crash but just freezes (hangs). We have a meditation screen which shows an animation while the user is meditating.
after about 15 to 20 minutes , it freezes the entire app and the audio also gets frozen. It works fine without issues in version though rive: ^0.13.20
same issue. App doesn't crash but just freezes (hangs). We have a meditation screen which shows an animation while the user is meditating.
after about 15 to 20 minutes , it freezes the entire app and the audio also gets frozen. It works fine without issues in version though
rive: ^0.13.20
Here's the raw stack trace from our Sentry dashboard :
ApplicationNotResponding: ANR
libc 0x0d30fc syscall
libc 0x0ac0b0 __futex_wait_ex
libc 0x0bb8a8 pthread_cond_wait
split_config.arm64_v8a.apk0x492ea0 std::_fl::__libcpp_condvar_wait[abi:nn210000] (pthread.h:122)
split_config.arm64_v8a.apk0x492ea0 std::_fl::condition_variable::wait (condition_variable.cpp:30)
split_config.arm64_v8a.apk0x4a7434 fml::AutoResetWaitableEvent::Wait (waitable_event.cc:75)
split_config.arm64_v8a.apk0x808f6c flutter::Shell::OnPlatformViewDestroyed (shell.cc:1045)
split_config.arm64_v8a.apk0x48726c flutter::PlatformView::NotifyDestroyed (platform_view.cc:83)
split_config.arm64_v8a.apk0x48726c flutter::PlatformViewAndroid::NotifyDestroyed (platform_view_android.cc:223)
split_config.arm64_v8a.apk0x489abc flutter::SurfaceDestroyed (platform_view_android_jni_impl.cc:291)
nativeSurfaceDestroyed
onSurfaceDestroyed (SourceFile:16)
i (SourceFile:7)
surfaceDestroyed (SourceFile:37)
surfaceDestroyed (SourceFile:5)
notifySurfaceDestroyed (SurfaceView.java:2447)
updateSurface (SurfaceView.java:1521)
setWindowStopped (SurfaceView.java:527)
surfaceDestroyed (SurfaceView.java:2323)
notifySurfaceDestroyed (ViewRootImpl.java:3261)
setWindowStopped (ViewRootImpl.java:3211)
setStoppedState (WindowManagerGlobal.java:692)
performStop (Activity.java:9750)
callActivityOnStop (ActivityThread.java:6489)
performStopActivityInner (ActivityThread.java:6469)
handleStopActivity (ActivityThread.java:6546)
execute (StopActivityItem.java:40)
execute (ActivityTransactionItem.java:60)
executeLifecycleItem (TransactionExecutor.java:271)
executeTransactionItems (TransactionExecutor.java:146)
execute (TransactionExecutor.java:120)
handleMessage (ActivityThread.java:3113)
dispatchMessage (Handler.java:109)
loopOnce (Looper.java:250)
loop (Looper.java:340)
main (ActivityThread.java:9933)
invoke
run (RuntimeInit.java:625)
main (ZygoteInit.java:957)
Thread: main
libc 0x0d30fc syscall
libc 0x0ac0b0 __futex_wait_ex
libc 0x0bb8a8 pthread_cond_wait
split_config.arm64_v8a.apk0x492ea0 std::_fl::__libcpp_condvar_wait[abi:nn210000] (pthread.h:122)
split_config.arm64_v8a.apk0x492ea0 std::_fl::condition_variable::wait (condition_variable.cpp:30)
split_config.arm64_v8a.apk0x4a7434 fml::AutoResetWaitableEvent::Wait (waitable_event.cc:75)
split_config.arm64_v8a.apk0x808f6c flutter::Shell::OnPlatformViewDestroyed (shell.cc:1045)
split_config.arm64_v8a.apk0x48726c flutter::PlatformView::NotifyDestroyed (platform_view.cc:83)
split_config.arm64_v8a.apk0x48726c flutter::PlatformViewAndroid::NotifyDestroyed (platform_view_android.cc:223)
split_config.arm64_v8a.apk0x489abc flutter::SurfaceDestroyed (platform_view_android_jni_impl.cc:291)
nativeSurfaceDestroyed
onSurfaceDestroyed (SourceFile:16)
i (SourceFile:7)
surfaceDestroyed (SourceFile:37)
surfaceDestroyed (SourceFile:5)
notifySurfaceDestroyed (SurfaceView.java:2447)
updateSurface (SurfaceView.java:1521)
setWindowStopped (SurfaceView.java:527)
surfaceDestroyed (SurfaceView.java:2323)
notifySurfaceDestroyed (ViewRootImpl.java:3261)
setWindowStopped (ViewRootImpl.java:3211)
setStoppedState (WindowManagerGlobal.java:692)
performStop (Activity.java:9750)
callActivityOnStop (ActivityThread.java:6489)
performStopActivityInner (ActivityThread.java:6469)
handleStopActivity (ActivityThread.java:6546)
execute (StopActivityItem.java:40)
execute (ActivityTransactionItem.java:60)
executeLifecycleItem (TransactionExecutor.java:271)
executeTransactionItems (TransactionExecutor.java:146)
execute (TransactionExecutor.java:120)
handleMessage (ActivityThread.java:3113)
dispatchMessage (Handler.java:109)
loopOnce (Looper.java:250)
loop (Looper.java:340)
main (ActivityThread.java:9933)
invoke
run (RuntimeInit.java:625)
main (ZygoteInit.java:957)
Can anyone confirm if this is still happening on the latest Rive Flutter release and the latest Flutter stable?
If yes, if you can provide minimal reproducible steps (or better a sample project) we can investigate this.
Can anyone confirm if this is still happening on the latest Rive Flutter release and the latest Flutter stable?
If yes, if you can provide minimal reproducible steps (or better a sample project) we can investigate this.
I just tested with following setup and don't see the spam anymore which I saw earlier when the Rive animation goes out of viewport.
environment: sdk: ">=3.10.1 <4.0.0" flutter: 3.38.3
rive: 0.14.0-dev.14
I tried with rive: 0.14.0-dev.14. This removed the spam (as compared to 0.14.0) but the crash still happens. This is our last lines of the log before the crash:
W/ImageReader_JNI(28647): Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
I/TRuntime.CctTransportBackend(28647): Status Code: 200
E/LayerState(28647): ERROR(Too many open files, -24). Failed to call parcel output->write(*acquireFence)
E/LayerState(28647): ERROR(Too many open files, -24). Failed to call parcel output.writeParcelable(*bufferData)
E/TransactionState(28647): ERROR(Too many open files, -24). Failed to call parcel s.write(*parcel)
E/SurfaceFlinger(28647): ERROR(Too many open files, -24). Failed to call parcel mutableState.writeToParcel(&data)
F/BLASTBufferQueue(28647): [2377329 SurfaceView[[REDACTED]/[REDACTED].MainActivity]#1] acquireNextBufferLocked failed to apply transaction. status=-24
2
E/RiveNative(28647): (12291) EGL_BAD_ALLOC - ../../../../platform/android/rive_native_android.cpp:297
F/[REDACTED](28647): runtime.cc:709] Runtime aborting...
If you can do without the new vector feathering, switching back from Factory.rive to the old Factory.flutter in the fileLoader circumvents this issue and prevents the app from crashing:
RiveWidgetBuilder(
fileLoader: FileLoader.fromAsset(
_PATH_,
riveFactory: Factory.flutter,
),
// ...
);
I am experiencing a build failure after upgrading to rive: ^0.14.0 in my existing project, while a fresh project with newer Gradle/Kotlin versions works correctly.
e: .../rive_native-0.1.0/android/src/main/kotlin/app/rive/rive_native/RiveNativePlugin.kt:116:1 Class 'RiveRenderTexture' is not abstract and does not implement abstract member 'onSurfaceDestroyed'. e: .../rive_native-0.1.0/android/src/main/kotlin/app/rive/rive_native/RiveNativePlugin.kt:149:5 'onSurfaceCleanup' overrides nothing.
Environment Comparison:
Feature | Existing Project (Failing) | Fresh Project (Working) -- | -- | -- Kotlin Version | 2.1.10 | 2.2.20 Android Gradle Plugin | 8.5.1 | 8.11.1 Gradle Config Style | Groovy (.gradle) | Kotlin DSL (.gradle.kts) NDK Version | 28.1.13356789 | (Default modern)