SonarSource/sonarqube · error · IllegalArgumentException
The minimum value for parameter
Error message
The minimum value for parameter %s is %s.
What it means
Thrown by validateMinExpirationDate when creating a user token whose expiration date is not in the future. SonarQube requires token expiration dates to be at least tomorrow (UTC); a same-day or past date is rejected. The message includes the parameter name 'expirationDate' and the minimum acceptable ISO date.
Solutions
- Pass an expirationDate at least one day in the future, computed against UTC.
- In automation, generate the date as UTC, e.g. LocalDate.now(ZoneOffset.UTC).plusDays(30), not the local 'today'.
- If no long-lived token is needed, omit expirationDate or use the maximum allowed lifespan per the server's token expiration policy.
Example fix
// before String expiration = LocalDate.now().toString(); // rejected: today is < min // after String expiration = LocalDate.now(ZoneOffset.UTC).plusDays(30).format(DateTimeFormatter.ISO_DATE);
Defensive patterns
Strategy: validation
Validate before calling
LocalDate min = LocalDate.now(ZoneOffset.UTC).plusDays(1);
if (expirationDate == null || expirationDate.isBefore(min)) {
throw new IllegalArgumentException("expirationDate must be at least " + min.format(DateTimeFormatter.ISO_DATE));
} Prevention
- Always compute expiration dates against UTC, not the local timezone.
- Add a minimum-expiry assertion in token-provisioning scripts.
- Prefer generous expirations (e.g. +30d) to avoid off-by-one failures at day boundaries.
When it happens
Trigger: Calling the api/users_tokens/generate (or user_tokens/create) web service with expirationDate set to today's date (UTC) or any past date. The check runs before token creation, comparing the parsed date to LocalDate.now(ZoneOffset.UTC).plusDays(1).
Common situations: Scripts automating token generation that compute 'end of today' as the expiry; CI pipelines passing current date due to timezone off-by-one (local timezone ahead/behind UTC); users picking today in the UI-driven API call; reuse of an old token's expiration date.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Message ' ' cannot be dismissed.
- %s
- a JVM option can't be empty and must start with '-'. The…
- Address contains invalid character: 0x%02x
- allowAllGroups can only be enabled when Auto-provisioning…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/ad29f84f3cb05df5.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/GenerateActionValidation.java:112
maxTokenLifetime.getDays()
.ifPresent(days -> {
throw new IllegalArgumentException(
String.format("Tokens expiring after %s are not allowed. Please use an expiration date.",
LocalDate.now(ZoneOffset.UTC).plusDays(days).format(DateTimeFormatter.ISO_DATE)));
});
}
static void compareExpirationDateToMaxAllowedLifetime(LocalDate expirationDate, LocalDate maxExpirationDate) {
if (expirationDate.isAfter(maxExpirationDate)) {
throw new IllegalArgumentException(
String.format("Tokens expiring after %s are not allowed. Please use a valid expiration date.",
maxExpirationDate.format(DateTimeFormatter.ISO_DATE)));
}
}
static void validateMinExpirationDate(LocalDate localDate) {
if (localDate.isBefore(LocalDate.now(ZoneOffset.UTC).plusDays(1))) {
throw new IllegalArgumentException(
String.format("The minimum value for parameter %s is %s.", PARAM_EXPIRATION_DATE, LocalDate.now(ZoneOffset.UTC).plusDays(1).format(DateTimeFormatter.ISO_DATE)));
}
}
static void validateParametersCombination(UserTokenSupport userTokenSupport, DbSession dbSession, Request request, TokenType tokenType) {
if (PROJECT_ANALYSIS_TOKEN.equals(tokenType)) {
validateProjectAnalysisParameters(userTokenSupport, dbSession, request);
} else if (GLOBAL_ANALYSIS_TOKEN.equals(tokenType)) {
validateGlobalAnalysisParameters(userTokenSupport, request);
}
}
private static void validateProjectAnalysisParameters(UserTokenSupport userTokenSupport, DbSession dbSession, Request request) {
checkArgument(userTokenSupport.sameLoginAsConnectedUser(request), "A Project Analysis Token cannot be generated for another user.");
checkArgument(request.param(PARAM_PROJECT_KEY) != null, "A projectKey is needed when creating Project Analysis Token");
userTokenSupport.validateProjectScanPermission(dbSession, request.param(PARAM_PROJECT_KEY));
}
View on GitHub (pinned to 184c821202)