spring-projects/spring-boot · error · IllegalArgumentException

'{}' is not within the valid range {} to {}

Error message

'{}' is not within the valid range {} to {}

What it means

Thrown by MavenBuildOutputTimestamp.toInstant as an IllegalArgumentException when an ISO-8601 timestamp parses successfully but falls outside the legal range for reproducible archive entries: 1980-01-01T00:00:02Z to 2099-12-31T23:59:59Z. The lower bound matches the minimum that the zip/tar formats can encode; the upper bound avoids overflow in legacy archivers. The instant, the min, and the max are all interpolated into the message.

Source

Thrown at build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/MavenBuildOutputTimestamp.java:92

	 * @return the parsed timestamp as an {@code Instant}, or {@code null}
	 * @throws IllegalArgumentException if the outputTimestamp is neither ISO 8601 nor an
	 * integer, or it's not within the valid range 1980-01-01T00:00:02Z to
	 * 2099-12-31T23:59:59Z
	 */
	@Nullable Instant toInstant() {
		if (!StringUtils.hasLength(this.timestamp)) {
			return null;
		}
		if (isNumeric(this.timestamp)) {
			return Instant.ofEpochSecond(Long.parseLong(this.timestamp));
		}
		if (this.timestamp.length() < 2) {
			return null;
		}
		try {
			Instant instant = OffsetDateTime.parse(this.timestamp).withOffsetSameInstant(ZoneOffset.UTC).toInstant();
			if (instant.isBefore(DATE_MIN) || instant.isAfter(DATE_MAX)) {
				throw new IllegalArgumentException(
						String.format("'%s' is not within the valid range %s to %s", instant, DATE_MIN, DATE_MAX));
			}
			return instant;
		}
		catch (DateTimeParseException pe) {
			throw new IllegalArgumentException(String.format("Can't parse '%s' to instant", this.timestamp));
		}
	}

	private static boolean isNumeric(String str) {
		for (char c : str.toCharArray()) {
			if (!Character.isDigit(c)) {
				return false;
			}
		}
		return true;
	}

View on GitHub (pinned to 5b2dbdbb8b)

Solutions

  1. Use a value within the 1980-01-01T00:00:02Z .. 2099-12-31T23:59:59Z range.
  2. For reproducible builds, prefer an integer epoch-second (e.g. the project's source date epoch) which bypasses the ISO range check via the numeric branch.
  3. If you genuinely want 'epoch', use the integer 315532800 (1980-01-01T00:00:00Z in seconds) or above.
  4. Check <project.build.outputTimestamp> in the POM and any parent/BOM inheritance.

Example fix

// before
<project.build.outputTimestamp>1970-01-01T00:00:00Z</project.build.outputTimestamp>
// after — within valid range
<project.build.outputTimestamp>1980-01-01T00:00:02Z</project.build.outputTimestamp>
// or numeric epoch seconds (no range check)
<project.build.outputTimestamp>315532800</project.build.outputTimestamp>
Defensive patterns

Strategy: validation

Validate before calling

// Validate an ISO timestamp is within the archive-legal range before passing it
import java.time.Instant, java.time.OffsetDateTime, java.time.ZoneOffset;

static final Instant MIN = Instant.parse("1980-01-01T00:00:02Z");
static final Instant MAX = Instant.parse("2099-12-31T23:59:59Z");

void checkRange(String isoTs) {
    Instant i = OffsetDateTime.parse(isoTs).withOffsetSameInstant(ZoneOffset.UTC).toInstant();
    if (i.isBefore(MIN) || i.isAfter(MAX))
        throw new IllegalArgumentException(i + " out of range " + MIN + ".." + MAX);
}

Prevention

When it happens

Trigger: Setting <project.build.outputTimestamp> (or a Spring Boot <outputTimestamp>) to a date before 1980 (e.g. 1970-01-01 for 'epoch') or after 2099; providing SOURCE_DATE_EPOCH-derived values as an ISO string instead of seconds; copying a historic timestamp from a migration.

Common situations: Teams setting outputTimestamp to 1970-01-01T00:00:00Z believing it gives reproducible builds (it is below the 1980 floor); CI injecting a build timestamp far in the past; misconfigured git-commit-id plumbing that supplies the first-commit date; date strings sourced from a system with a wrong clock.

Related errors


AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04). Data as JSON: /data/errors/1868f651d8a7ffd3.json. Report an issue: GitHub.