microg/GmsCore · error · IllegalArgumentException

durationMillis must be greater than 0

Error message

durationMillis must be greater than 0

What it means

LocationRequest.setExpirationDuration() (deprecated) requires a strictly positive lifetime in milliseconds for the request; zero or negative values are meaningless, so IllegalArgumentException is thrown. The deprecated method is called internally by readLocationRequest when converting legacy parcels.

Source

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

    public boolean isPassive() {
        return priority == Priority.PRIORITY_PASSIVE;
    }

    /**
     * If this request is {@link Priority#PRIORITY_HIGH_ACCURACY}, this will delay delivery of initial low accuracy locations for a
     * small amount of time in case a high accuracy location can be delivered instead.
     */
    public boolean isWaitForAccurateLocation() {
        return waitForAccurateLocation;
    }

    /**
     * @deprecated Use {@link LocationRequest.Builder#setDurationMillis(long)} instead. May be removed in a future release.
     */
    @Deprecated
    @NonNull
    public LocationRequest setExpirationDuration(long durationMillis) {
        if (durationMillis <= 0) throw new IllegalArgumentException("durationMillis must be greater than 0");
        this.durationMillis = durationMillis;
        return this;
    }

    /**
     * @deprecated Use {@link LocationRequest.Builder#setDurationMillis(long)} instead. Using this method will express the expiration time in
     * terms of duration, which may give unexpected results. May be removed in a future release.
     */
    @Deprecated
    @NonNull
    public LocationRequest setExpirationTime(long elapsedRealtime) {
        this.durationMillis = Math.max(1, elapsedRealtime - SystemClock.elapsedRealtime());
        return this;
    }

    /**
     * @deprecated Use {@link LocationRequest.Builder#setMinUpdateIntervalMillis(long)} instead. May be removed in a future release.
     */

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Pass a positive duration, e.g. setExpirationDuration(TimeUnit.MINUTES.toMillis(10))
  2. Migrate to LocationRequest.Builder.setDurationMillis(long), the non-deprecated replacement
  3. Validate computed durations are > 0 before setting

Example fix

// before
request.setExpirationDuration(0); // throws
// after
request.setExpirationDuration(TimeUnit.MINUTES.toMillis(10));
// or modern equivalent:
LocationRequest req = new LocationRequest.Builder(priority, intervalMillis)
    .setDurationMillis(TimeUnit.MINUTES.toMillis(10))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (durationMillis <= 0) {
    throw new IllegalStateException("Expiration duration must be positive");
}
request.setExpirationDuration(durationMillis);

Type guard

static boolean isValidDuration(long v) { return v > 0; }

Try / catch

try { request.setExpirationDuration(d); } catch (IllegalArgumentException e) { request.setExpirationDuration(TimeUnit.MINUTES.toMillis(10)); }

Prevention

When it happens

Trigger: Calling setExpirationDuration(0) or a negative value; also triggered indirectly when a legacy Parcelable LocationRequest carries a non-positive durationMillis.

Common situations: Passing a config value defaulting to 0/-1; computing duration via subtraction that underflowed; using the deprecated API on newer play-services versions where LocationRequest.Builder.setDurationMillis is preferred.

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/cdad10cd1a763584. Report an issue: GitHub.