microg/GmsCore · error · IllegalArgumentException

Geofence must be created using Geofence.Builder.

Error message

Geofence must be created using Geofence.Builder.

What it means

addGeofence() only accepts instances of ParcelableGeofence, the internal type produced by Geofence.Builder.build(). Passing any other Geofence implementation (e.g. a mock, a subclass, or a foreign implementation) cannot be marshaled into the request, so IllegalArgumentException is thrown.

Source

Thrown at play-services-location/src/main/java/com/google/android/gms/location/GeofencingRequest.java:105

    /**
     * A builder that builds {@link GeofencingRequest}.
     */
    public static class Builder {
        private List<Geofence> geofences = new ArrayList<>();
        private @InitialTrigger int initialTrigger = INITIAL_TRIGGER_ENTER | INITIAL_TRIGGER_DWELL;

        /**
         * Adds a geofence to be monitored by geofencing service.
         *
         * @param geofence the geofence to be monitored. The geofence must be built with {@link Geofence.Builder}.
         * @return the builder object itself for method chaining
         * @throws IllegalArgumentException if the geofence is not built with {@link Geofence.Builder}.
         * @throws NullPointerException     if the given geofence is null
         */
        @NonNull
        public GeofencingRequest.Builder addGeofence(Geofence geofence) {
            if (geofence == null) throw new NullPointerException("geofence can't be null.");
            if (!(geofence instanceof ParcelableGeofence)) throw new IllegalArgumentException("Geofence must be created using Geofence.Builder.");
            geofences.add(geofence);
            return this;
        }

        /**
         * Adds all the geofences in the given list to be monitored by geofencing service.
         *
         * @param geofences the geofences to be monitored. The geofences in the list must be built with {@link Geofence.Builder}.
         * @return the builder object itself for method chaining
         * @throws IllegalArgumentException if the geofence is not built with {@link Geofence.Builder}.
         */
        @NonNull
        public GeofencingRequest.Builder addGeofences(List<Geofence> geofences) {
            if (geofences != null) {
                for (Geofence geofence : geofences) {
                    if (geofence != null) addGeofence(geofence);
                }
            }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Always create geofences via Geofence.Builder().build() before adding them to the request
  2. In tests, use the real Geofence.Builder to construct fixtures instead of mocks
  3. Avoid custom Geofence implementations; the public API expects builder-produced instances

Example fix

// before
Geofence mockFence = Mockito.mock(Geofence.class);
requestBuilder.addGeofence(mockFence); // throws
// after
Geofence fence = new Geofence.Builder()
    .setRequestId("fence1")
    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
    .setCircularRegion(lat, lng, 100f)
    .setExpirationDuration(3600000)
    .build();
requestBuilder.addGeofence(fence);
Defensive patterns

Strategy: validation

Validate before calling

if (!(geofence instanceof ParcelableGeofence)) {
    throw new IllegalStateException("Geofence must come from Geofence.Builder.build()");
}
requestBuilder.addGeofence(geofence);

Type guard

static boolean isBuilderCreated(Geofence g) { return g instanceof ParcelableGeofence; }

Try / catch

try { builder.addGeofence(fence); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Geofence.Builder")) { throw new IllegalStateException("Recreate fence with Geofence.Builder", e); } throw e; }

Prevention

When it happens

Trigger: Calling addGeofence(geofence) where geofence is not an instanceof ParcelableGeofence — e.g. created via Mockito, a custom Geofence implementation, or deserialized from another source.

Common situations: Unit tests passing mocked Geofences into a real builder; custom Geofence implementations from wrapper libraries; reflection-based construction bypassing Geofence.Builder.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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