microg/GmsCore · error · IllegalArgumentException
intervalMillis must be greater than 0
Error message
intervalMillis must be greater than 0
What it means
setDurationMillis validates that the request duration is strictly positive. A duration of 0 or less means the request would never receive updates, so the builder rejects it. Note the misleading message text says 'intervalMillis' but the checked value is durationMillis.
Source
Thrown at play-services-location/src/main/java/com/google/android/gms/location/LocationRequest.java:680
}
@NonNull
@PublicApi(exclude = true)
@RequiresPermission(anyOf = {"android.permission.WRITE_SECURE_SETTINGS", "android.permission.LOCATION_BYPASS"})
public Builder setBypass(boolean bypass) {
this.bypass = bypass;
return this;
}
/**
* Sets the duration of this request. A location request will not receive any locations after it has expired, and will be
* removed shortly thereafter. A value of {@link Long#MAX_VALUE} implies an infinite duration.
* <p>
* The default value is {@link Long#MAX_VALUE}.
*/
@NonNull
public Builder setDurationMillis(long durationMillis) {
if (durationMillis <= 0) throw new IllegalArgumentException("intervalMillis must be greater than 0");
this.durationMillis = durationMillis;
return this;
}
/**
* Sets the {@link Granularity} of locations returned for this request. This controls whether fine or coarse locations may be
* returned.
* <p>
* The default value is {@link Granularity#GRANULARITY_PERMISSION_LEVEL}.
*/
@NonNull
public Builder setGranularity(@Granularity int granularity) {
GranularityUtil.checkValidGranularity(granularity);
this.granularity = granularity;
return this;
}
/**View on GitHub (pinned to 157c9d86ac)
Solutions
- Pass a positive duration; to keep the request alive indefinitely, simply do not call setDurationMillis (default is Long.MAX_VALUE).
- Clamp computed durations: Math.max(1, deadlineMillis - System.currentTimeMillis()).
- If 0 was meant as 'unlimited', remove the call rather than setting 0.
Example fix
// before builder.setDurationMillis(0); // intended 'no limit' // after builder.setDurationMillis(Long.MAX_VALUE); // or omit the call entirely (default)
Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidDuration(long durationMillis) {
return durationMillis > 0;
}
if (!isValidDuration(duration)) duration = Long.MAX_VALUE; // treat <=0 as infinite Type guard
static boolean isPositive(long v) { return v > 0; } Try / catch
try {
return builder.setDurationMillis(duration);
} catch (IllegalArgumentException e) {
if (!e.getMessage().contains("greater than 0")) throw e;
return builder; // keep default Long.MAX_VALUE duration
} Prevention
- Remember 0 is invalid here — 'unlimited' means omitting the call or Long.MAX_VALUE.
- When deriving duration from a deadline, check the deadline is in the future before subtracting.
- Note the exception message says 'intervalMillis' even though it's about duration — match on the setter name, not just the message.
When it happens
Trigger: Calling builder.setDurationMillis(0) or any negative value, e.g. setDurationMillis(-1) or setDurationMillis(0) intending to mean 'no duration limit' instead of using Long.MAX_VALUE (the default).
Common situations: Developers passing 0 thinking it disables the duration limit; computing duration from a deadline that already passed (deadline - now <= 0); copying a value from code that used 0 as a sentinel for 'infinite'.
Related errors
- maxUpdateAgeMillis must be greater than or equal to 0, or IM
- maxUpdateDelayMillis must be greater than or equal to 0
- deleteAll was set to true but keys were also provided
- Element in keys cannot be null or empty
- retrieveAll was set to true but other constraint(s) was also
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/19fe0c0b90c81e80.
Report an issue: GitHub.