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

  1. Pass a positive duration; to keep the request alive indefinitely, simply do not call setDurationMillis (default is Long.MAX_VALUE).
  2. Clamp computed durations: Math.max(1, deadlineMillis - System.currentTimeMillis()).
  3. 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

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


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