microg/GmsCore · error · IOException

Could not find suitable preview frames per second range.

Error message

Could not find suitable preview frames per second range.

What it means

CameraSource.pickFpsRange() scans the camera's supported preview FPS ranges for one closest to the requested FPS and throws IOException if none was selected (selectedFpsRange remains null). This means the camera exposes no usable supportedPreviewFpsRange entries compatible with the request.

Source

Thrown at play-services-vision-common/src/main/java/com/google/android/gms/vision/CameraSource.java:371

        }
        throw new IOException("Could not find requested camera.");
    }

    private int[] pickFpsRange(Camera camera) throws IOException {
        int requestsFpms = (int) (requestedFps * 1000.0F);
        int[] selectedFpsRange = null;
        int selectedPreviewFpsOffset = Integer.MAX_VALUE;

        for (int[] previewFpsRange : camera.getParameters().getSupportedPreviewFpsRange()) {
            int minOffset = requestsFpms - previewFpsRange[0];
            int maxOffset = requestsFpms - previewFpsRange[1];
            int previewFpsOffset;
            if ((previewFpsOffset = Math.abs(minOffset) + Math.abs(maxOffset)) < selectedPreviewFpsOffset) {
                selectedFpsRange = previewFpsRange;
                selectedPreviewFpsOffset = previewFpsOffset;
            }
        }
        if (selectedFpsRange == null) throw new IOException("Could not find suitable preview frames per second range.");
        return selectedFpsRange;
    }

    private SizePair pickCameraSize(Camera camera) throws IOException {
        ArrayList<SizePair> sizeCandidates = new ArrayList<>();
        for (Camera.Size previewSize : camera.getParameters().getSupportedPreviewSizes()) {
            float previewAspectRatio = (float) (previewSize).width / (float) previewSize.height;
            for (Camera.Size pictureSize : camera.getParameters().getSupportedPictureSizes()) {
                float pictureAspectRatio = (float) (pictureSize).width / (float) pictureSize.height;
                if (Math.abs(previewAspectRatio - pictureAspectRatio) < 0.01F) { // Approximately same aspect ratio
                    sizeCandidates.add(new SizePair(previewSize, pictureSize));
                    break;
                }
            }
        }
        if (sizeCandidates.size() == 0) {
            for (Camera.Size previewSize : camera.getParameters().getSupportedPreviewSizes()) {
                sizeCandidates.add(new SizePair(previewSize, null));

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Check camera.getParameters().getSupportedPreviewFpsRange() for emptiness before start() and choose a fallback camera/facing
  2. Adjust requestedFps to a standard value (e.g. 30) that devices commonly support
  3. Test on the failing device and log getSupportedPreviewFpsRange() to see what is exposed
  4. Catch IOException around start() and degrade gracefully (show a camera-unavailable state)

Example fix

// before
CameraSource source = new CameraSource.Builder(context, detector)
    .setRequestedFps(60.0f)
    .build();
source.start(); // may throw if no suitable fps range
// after
try {
    CameraSource source = new CameraSource.Builder(context, detector)
        .setRequestedFps(30.0f)
        .build();
    source.start();
} catch (IOException e) {
    Log.e(TAG, "No suitable preview FPS range on this device", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

List<int[]> ranges = camera.getParameters().getSupportedPreviewFpsRange();
if (ranges == null || ranges.isEmpty()) { /* pick a different camera or fail gracefully */ }

Type guard

null

Try / catch

try {
    cameraSource.start();
} catch (IOException e) {
    // no usable FPS range: degrade or switch camera
}

Prevention

When it happens

Trigger: Calling start() when the device's Camera.Parameters.getSupportedPreviewFpsRange() returns no ranges (empty/unavailable), leaving selectedFpsRange null after the selection loop.

Common situations: Virtual emulators or exotic camera HALs reporting no FPS ranges; drivers returning malformed empty lists; requesting FPS outside everything the device supports.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/5898c95ac7f416e6. Report an issue: GitHub.