microg/GmsCore · error · IllegalStateException

CameraUpdateFactory is not initialized

Error message

CameraUpdateFactory is not initialized

What it means

BitmapDescriptorFactory also delegates to a backend-supplied IBitmapDescriptorFactoryDelegate installed via setDelegate. getDelegate() throws IllegalStateException (with the same, slightly misleading message 'CameraUpdateFactory is not initialized') when no map backend registered, so any defaultMarker()/fromResource() style call fails.

Source

Thrown at play-services-maps/src/main/java/com/google/android/gms/maps/model/BitmapDescriptorFactory.java:21

 * SPDX-License-Identifier: Apache-2.0
 */

package com.google.android.gms.maps.model;

import androidx.annotation.NonNull;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.internal.ICameraUpdateFactoryDelegate;
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate;
import org.microg.gms.common.Hide;

public class BitmapDescriptorFactory {
    private static IBitmapDescriptorFactoryDelegate delegate;
    @Hide
    public static void setDelegate(@NonNull IBitmapDescriptorFactoryDelegate delegate) {
        BitmapDescriptorFactory.delegate = delegate;
    }
    private static IBitmapDescriptorFactoryDelegate getDelegate() {
        if (delegate == null) throw new IllegalStateException("CameraUpdateFactory is not initialized");
        return delegate;
    }
}

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Initialize the map view/backend (MapsInitializer / map fragment) before using BitmapDescriptorFactory
  2. Ensure the microG maps backend is installed so its init calls BitmapDescriptorFactory.setDelegate(...)
  3. In tests, install a mock IBitmapDescriptorFactoryDelegate via BitmapDescriptorFactory.setDelegate first

Example fix

// before
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.pin); // delegate null
// after
mapFragment.getMapAsync(googleMap -> {
    BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.pin);
    markerOptions.icon(icon);
});
Defensive patterns

Strategy: try-catch

Validate before calling

mapFragment.getMapAsync(googleMap -> {
    BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.pin);
});

Try / catch

try { BitmapDescriptorFactory.defaultMarker(); } catch (IllegalStateException e) { /* defer until map backend initialized */ }

Prevention

When it happens

Trigger: Calling BitmapDescriptorFactory.defaultMarker(), fromResource(), fromBitmap(), etc. before a map backend initialized (no setDelegate call), such as building marker icons in a ViewModel or before MapsInitializer runs.

Common situations: Pre-computing marker icons before the map loads; running unit tests without a fake delegate; missing microG maps backend so neither factory delegate is registered.

Related errors


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