microg/GmsCore · error · IllegalArgumentException

maxUpdateAgeMillis must be greater than 0

Error message

maxUpdateAgeMillis must be greater than 0

What it means

LastLocationRequest.Builder.setMaxUpdateAgeMillis() sets the maximum acceptable age of a returned location; only strictly positive values are meaningful, so the builder throws IllegalArgumentException for values <= 0.

Source

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

        /**
         * 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}.
         */
        public LastLocationRequest.Builder setGranularity(@Granularity int granularity) {
            GranularityUtil.checkValidGranularity(granularity);
            this.granularity = granularity;
            return this;
        }

        /**
         * Sets the maximum age of any location returned for this request. A value of {@link Long#MAX_VALUE} represents an effectively unbounded maximum age.
         * <p>
         * The default value is {@link Long#MAX_VALUE}.
         */
        public LastLocationRequest.Builder setMaxUpdateAgeMillis(long maxUpdateAgeMillis) {
            if (maxUpdateAgeMillis <= 0) throw new IllegalArgumentException("maxUpdateAgeMillis must be greater than 0");
            this.maxUpdateAgeMillis = maxUpdateAgeMillis;
            return this;
        }

        /**
         * Builds a new {@link LastLocationRequest}.
         */
        public LastLocationRequest build() {
            LastLocationRequest request = new LastLocationRequest();
            request.maxUpdateAgeMillis = maxUpdateAgeMillis;
            request.granularity = granularity;
            request.bypass = bypass;
            request.moduleId = moduleId;
            request.impersonation = impersonation;
            return request;
        }
    }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Pass a positive millisecond value (e.g. 10000 for 10 seconds)
  2. Use Long.MAX_VALUE for an effectively unbounded maximum age
  3. Clamp or validate config-derived values before calling the setter

Example fix

// before
long age = config.getLong("maxAge", 0); // 0 default
builder.setMaxUpdateAgeMillis(age); // throws
// after
long age = config.getLong("maxAge", 10000L);
if (age > 0) builder.setMaxUpdateAgeMillis(age);
Defensive patterns

Strategy: validation

Validate before calling

if (maxUpdateAgeMillis <= 0) {
    maxUpdateAgeMillis = Long.MAX_VALUE; // or a sensible default like 10_000L
}
builder.setMaxUpdateAgeMillis(maxUpdateAgeMillis);

Type guard

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

Try / catch

try { builder.setMaxUpdateAgeMillis(age); } catch (IllegalArgumentException e) { builder.setMaxUpdateAgeMillis(Long.MAX_VALUE); }

Prevention

When it happens

Trigger: Calling setMaxUpdateAgeMillis(0) or any negative value (including accidentally passing Long.MIN_VALUE or an unset/default sentinel like -1 from config).

Common situations: Passing a config value defaulting to -1 or 0; integer overflow when computing the age from seconds; mixing up 'unbounded' (Long.MAX_VALUE) with 0.

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