microg/GmsCore · error · IllegalArgumentException

illegal fastest interval:

Error message

illegal fastest interval: 

What it means

LocationRequest.setFastestInterval(long) throws IllegalArgumentException when the supplied fastestIntervalMillis is negative. The fastest interval defines the minimum time between location updates, so a negative value is meaningless and rejected before the field is set. This is a pre-call validation guard in the library, not an async failure.

Source

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

    /**
     * @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.
     */
    @Deprecated
    @NonNull
    public LocationRequest setFastestInterval(long fastestIntervalMillis) throws IllegalArgumentException {
        if (fastestIntervalMillis < 0) throw new IllegalArgumentException("illegal fastest interval: " + fastestIntervalMillis);
        this.minUpdateIntervalMillis = fastestIntervalMillis;
        explicitFastestInterval = true; // FIXME: Remove
        return this;
    }

    /**
     * @deprecated Use {@link LocationRequest.Builder#setIntervalMillis(long)} instead. May be removed in a future release.
     */
    @Deprecated
    @NonNull
    public LocationRequest setInterval(long intervalMillis) throws IllegalArgumentException {
        if (intervalMillis < 0) throw new IllegalArgumentException("intervalMillis must be greater than or equal to 0");
        if (this.minUpdateIntervalMillis == this.intervalMillis / 6) {
            this.minUpdateIntervalMillis = intervalMillis / 6;
        }
        if (this.maxUpdateAgeMillis == this.intervalMillis) {
            this.maxUpdateAgeMillis = intervalMillis;
        }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Clamp or reject negative values before calling setFastestInterval: use Math.max(0, intervalMillis).
  2. Use -1 only as 'unset' in your own code and skip the call when it is -1.
  3. Migrate to the Builder API: new LocationRequest.Builder(intervalMillis).setMinUpdateIntervalMillis(...) which validates centrally.

Example fix

// before
LocationRequest request = new LocationRequest()
    .setInterval(intervalMillis)
    .setFastestInterval(fastestIntervalMillis); // throws if negative
// after
LocationRequest request = new LocationRequest.Builder(intervalMillis)
    .setMinUpdateIntervalMillis(Math.max(0, fastestIntervalMillis))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// Java
public static void checkFastestInterval(long fastestIntervalMillis) {
    if (fastestIntervalMillis < 0) {
        throw new IllegalArgumentException("fastestIntervalMillis must be >= 0, got " + fastestIntervalMillis);
    }
}
// call checkFastestInterval(v) before request.setFastestInterval(v)

Type guard

static boolean isValidInterval(long millis) { return millis >= 0; }

Try / catch

// Java
try {
    request.setFastestInterval(fastestIntervalMillis);
} catch (IllegalArgumentException e) {
    Log.w("LocationReq", "Invalid fastest interval " + fastestIntervalMillis + ", using default", e);
    request.setFastestInterval(0);
}

Prevention

When it happens

Trigger: Calling the deprecated LocationRequest.setFastestInterval() with a negative long, e.g. setFastestInterval(-1000), or passing a computed variable that underflowed or was initialized to -1 as a sentinel.

Common situations: Using -1 as a 'default/unset' sentinel for the interval; subtracting from a small interval causing long underflow; porting old code where -1 meant 'automatic'; config values parsed from negative settings.

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