microg/GmsCore · error · IllegalArgumentException
Expiration not set.
Error message
Expiration not set.
What it means
build() requires an expiration to be configured; expirationTime defaults to Long.MIN_VALUE meaning 'not set'. A geofence with no expiration would never be cleaned up, so the library rejects it with IllegalArgumentException.
Source
Thrown at play-services-location/src/main/java/com/google/android/gms/location/Geofence.java:118
private int loiteringDelay = -1;
private int notificationResponsiveness;
private String requestId;
private @TransitionTypes int transitionTypes;
/**
* Creates a geofence object.
*
* @throws IllegalArgumentException if any parameters are not set or out of range
*/
public Geofence build() throws IllegalArgumentException {
if (requestId == null) {
throw new IllegalArgumentException("Request ID not set.");
} else if (transitionTypes == 0) {
throw new IllegalArgumentException("Transition types not set.");
} else if ((transitionTypes & GEOFENCE_TRANSITION_DWELL) > 0 && loiteringDelay < 0) {
throw new IllegalArgumentException("Non-negative loitering delay needs to be set when transition types include GEOFENCE_TRANSITION_DWELLING.");
} else if (expirationTime == Long.MIN_VALUE) {
throw new IllegalArgumentException("Expiration not set.");
} else if (regionType == -1) {
throw new IllegalArgumentException("Geofence region not set.");
} else if (notificationResponsiveness < 0) {
throw new IllegalArgumentException("Notification responsiveness should be nonnegative.");
} else {
return new ParcelableGeofence(requestId, expirationTime, regionType, latitude, longitude, radius, transitionTypes, notificationResponsiveness, loiteringDelay);
}
}
/**
* Sets the region of this geofence. The geofence represents a circular area on a flat, horizontal plane.
*
* @param latitude latitude in degrees, between -90 and +90 inclusive
* @param longitude longitude in degrees, between -180 and +180 inclusive
* @param radius radius in meters
*/
public Builder setCircularRegion(@FloatRange(from = -90.0d, to = 90.0d) double latitude, @FloatRange(from = -180.0d, to = 180.0d) double longitude, @FloatRange(from = 0.0d, fromInclusive = false) float radius) {
this.regionType = 1;View on GitHub (pinned to 157c9d86ac)
Solutions
- Call setExpirationDuration(millis) with a positive duration before build()
- Use setExpirationDuration(Geofence.NEVER_EXPIRE) if the fence should persist until explicitly removed
Example fix
// before
Geofence fence = new Geofence.Builder()
.setRequestId("fence1")
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(lat, lng, radius)
.build(); // throws
// after
Geofence fence = new Geofence.Builder()
.setRequestId("fence1")
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(lat, lng, radius)
.setExpirationDuration(60 * 60 * 1000L)
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (expirationDurationMillis <= 0 && expirationDurationMillis != Geofence.NEVER_EXPIRE) {
throw new IllegalStateException("Set a positive expiration duration");
} Try / catch
try { return builder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Expiration")) { builder.setExpirationDuration(Geofence.NEVER_EXPIRE); return builder.build(); } throw e; } Prevention
- Always set setExpirationDuration() — use Geofence.NEVER_EXPIRE for persistent fences
- Centralize geofence creation in one helper with sensible defaults
When it happens
Trigger: Calling build() without calling setExpirationDuration(long) or setExpirationTime(long) on the builder.
Common situations: Omitting expiration in minimal builder chains; confusion because some Google samples use NEVER_EXPIRATION (setExpirationDuration(NEVER_EXPIRE)) while this field must be explicitly set; copying pre-Builder ParcelableGeofence code.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- invalid radius:
- invalid latitude:
- invalid longitude:
- Transition types not set.
- Non-negative loitering delay needs to be set when transition
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/27c6b5c26f9ac61a.
Report an issue: GitHub.