Android: every <Camera> mount leaks its SurfaceView and camera output stream

Author: GognCreated Sep 4, 2026Updated Sep 4, 2026
Labels🐛 bug

Prerequisites

Reproduction

https://github.com/Gogn/react-native-vision-camera_issue-reproducing

Steps to reproduce

  1. Clone the attached repository or create a bare React-Native project
  2. Run the app
  3. Watch logcat: adb logcat | grep -E "SurfaceView\[|BufferQueue has been abandoned|Camera3-OutputStream"
  4. Optionally check a heap dump: adb shell am dumpheap com.vcpreviewleak /something/heap.hprof

What did you expect to happen?

Mounting and unmounting a screen with <Camera> should release the SurfaceView and its camera output stream. After some time, the number of live SurfaceView / PreviewView / HybridPreviewView instances should stay at the same amount regardless of how many times the component is mounted.

What actually happened?

Every mount leaks the preview's SurfaceView and creates a new camera output stream, nothing is released. After the surface is destroyed on unmount, the camera pipeline keeps trying to queue buffers into the abandoned BufferQueue.

With every new mount/unmount cycle:

  • a new SurfaceView surface is created and the previous one is never released
  • Those surfaces emitts BufferQueue has been abandoned errors after being destroyed
  • a new camera3 output stream is created
  • just one MainActivity throughout, so this is not an Activity leak

Affected platforms

Android (emulator)

Device(s) affected

Android 11 emulator, arm64-v8a

VisionCamera version

5.2.3

React Native version

0.86.3

React Native architecture

New Architecture (Fabric / bridgeless)

Features being used

  • Preview
  • Photo capture
  • Video capture
  • Frame Processors (worklets)
  • Skia Frame Processors
  • Code/Barcode Scanner
  • Location metadata
  • Multi-cam
  • Depth data
  • HDR / custom dynamic range
  • Custom format / FPS / resolution

Relevant logs / stack trace

One cycle, showing the surface being destroyed and then still written to:

D SurfaceViewImpl: Surface destroyed.
D SurfaceViewImpl: Surface closed androidx.camera.core.SurfaceRequest@f6f2cf
E BufferQueueProducer: [1e02dbf SurfaceView[com.vcpreviewleak/com.vcpreviewleak.MainActivity]#431(BLAST Consumer)431](id:7f8e000001af,api:4,p:596,c:32654) queueBuffer: BufferQueue has been abandoned
E Surface  : queueBuffer: error queuing buffer, -19
D StreamStateObserver: Update Preview stream state to IDLE
I HybridPreviewViewSpec: PreviewView stopped!
E Camera3-OutputStream: returnBufferCheckedLocked: Stream 544: Error queueing buffer to native window: No such device (-19)
E Camera3-OutputStream: getBufferLockedCommon: Stream 544: Can't dequeue next output buffer: No such device (-19)
D CXCP    : Closing capture session for CaptureSessionState-432

Heap dump after 30 cycles (app heap only):

     31  com.margelo.nitro.camera.views.HybridPreviewView
     31  com.margelo.nitro.camera.hybrids.outputs.HybridPreviewOutput
     25  com.margelo.nitro.camera.hybrids.HybridCameraSession
     25  com.margelo.nitro.camera.hybrids.HybridCameraController
      9  com.margelo.nitro.camera.hybrids.inputs.HybridCameraDevice

Additional context

  • Seems not a duplicate of #4095. That issue was fixed by nitro#1460 and the fix is working here.
  • In our app the leaked SurfaceView sits inside a navigation screen, so it pins the react-native-screens and that screen whole view hierarchy. The leak becomes Java heap growth.

Submission

  • The reproduction I linked is either (preferred) a PR against this repo that adds a failing harness test following the harness-tests README, or (fallback) a public repo that reproduces the bug on a fresh clone. I understand the issue will be closed without one.
  • I pasted logs as text (not screenshots).
  • I wrote this report in my own words. I did not paste AI-generated descriptions of the bug.

Source: mrousavy/react-native-vision-camera