apolloconfig/apollo · error · BadRequestException
Token expires exceeds max allowed days:%s
Error message
Token expires exceeds max allowed days:%s
What it means
Thrown by UserTokenService.resolveExpires() when the expiry date exceeds now + portalConfig.userTokenMaxExpireDays() days. The max is computed via Calendar.add(DAY_OF_YEAR, userTokenMaxExpireDays()). The %s placeholder is filled with the configured max days value. BadRequestException → HTTP 400.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/UserTokenService.java:400
}
private Date resolveExpires(Date requestedExpires, Date now) {
Date expires = requestedExpires;
if (expires == null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.add(Calendar.DAY_OF_YEAR, portalConfig.userTokenDefaultExpireDays());
expires = calendar.getTime();
}
if (!expires.after(now)) {
throw new BadRequestException("Token expires must be in the future");
}
Calendar maxCalendar = Calendar.getInstance();
maxCalendar.setTime(now);
maxCalendar.add(Calendar.DAY_OF_YEAR, portalConfig.userTokenMaxExpireDays());
if (expires.after(maxCalendar.getTime())) {
throw new BadRequestException("Token expires exceeds max allowed days:%s",
portalConfig.userTokenMaxExpireDays());
}
return expires;
}
private int resolveRateLimit(Integer rateLimit) {
return rateLimit == null ? 0 : rateLimit;
}
private void validateOperator(String operator) {
if (StringUtils.isBlank(operator)) {
throw new BadRequestException("operator should not be null or empty");
}
}
private UserTokenInfo toInfo(UserToken userToken) {
return toInfo(userToken, new Date());
}View on GitHub (pinned to d95fc18d11)
Solutions
- Reduce the requested expiry to within portalConfig.userTokenMaxExpireDays() days from now.
- If a longer-lived token is genuinely needed, increase the userTokenMaxExpireDays configuration on the portal server.
- Leave expires as null to get the default (userTokenDefaultExpireDays), which is always within the max.
Example fix
// before — assuming maxExpireDays=90 Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 365); request.setExpires(cal.getTime()); // after cal.add(Calendar.DAY_OF_YEAR, 90); request.setExpires(cal.getTime());
Defensive patterns
Strategy: validation
Validate before calling
int maxDays = portalConfig.userTokenMaxExpireDays();
Calendar maxCal = Calendar.getInstance();
maxCal.add(Calendar.DAY_OF_YEAR, maxDays);
if (request.getExpires() != null && request.getExpires().after(maxCal.getTime())) {
request.setExpires(maxCal.getTime()); // or throw
}
userTokenService.createToken(request, operator); Type guard
static boolean isExpiryWithinMax(Date expires, int maxDays) {
if (expires == null) return true;
Calendar maxCal = Calendar.getInstance();
maxCal.add(Calendar.DAY_OF_YEAR, maxDays);
return !expires.after(maxCal.getTime());
} Try / catch
try {
userTokenService.createToken(request, operator);
} catch (BadRequestException e) {
if (e.getMessage().contains("exceeds max allowed days")) {
return Response.status(400).entity("Expiry exceeds the configured maximum lifetime").build();
}
throw e;
} Prevention
- Use the default expiry (null) which is always within the max.
- Check portalConfig.userTokenMaxExpireDays() before setting a custom expiry.
When it happens
Trigger: Calling createToken() with request.setExpires() set to a date beyond the server's configured maximum token lifetime. For example, if userTokenMaxExpireDays is 90 and the requested expiry is 120 days out, this throws.
Common situations: Client requests a long-lived token (e.g., 1 year) but the server's portalConfig.userTokenMaxExpireDays is set to a shorter ceiling. The max-days config was tightened after tokens were already issued with longer expiry.
Related errors
- Invalid user token status:%s
- Invalid user token operation:%s
- Token name can not be blank
- Token namespace scope can not be null
- Token expires must be in the future
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/90ab80da85c4d41f.
Report an issue: GitHub.