{"record":{"id":"90ab80da85c4d41f","repo":"apolloconfig/apollo","slug":"token-expires-exceeds-max-allowed-days-s","errorCode":null,"errorMessage":"Token expires exceeds max allowed days:%s","messagePattern":"Token expires exceeds max allowed days:(.+?)","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/UserTokenService.java","lineNumber":400,"sourceCode":"  }\n\n  private Date resolveExpires(Date requestedExpires, Date now) {\n    Date expires = requestedExpires;\n    if (expires == null) {\n      Calendar calendar = Calendar.getInstance();\n      calendar.setTime(now);\n      calendar.add(Calendar.DAY_OF_YEAR, portalConfig.userTokenDefaultExpireDays());\n      expires = calendar.getTime();\n    }\n    if (!expires.after(now)) {\n      throw new BadRequestException(\"Token expires must be in the future\");\n    }\n\n    Calendar maxCalendar = Calendar.getInstance();\n    maxCalendar.setTime(now);\n    maxCalendar.add(Calendar.DAY_OF_YEAR, portalConfig.userTokenMaxExpireDays());\n    if (expires.after(maxCalendar.getTime())) {\n      throw new BadRequestException(\"Token expires exceeds max allowed days:%s\",\n          portalConfig.userTokenMaxExpireDays());\n    }\n    return expires;\n  }\n\n  private int resolveRateLimit(Integer rateLimit) {\n    return rateLimit == null ? 0 : rateLimit;\n  }\n\n  private void validateOperator(String operator) {\n    if (StringUtils.isBlank(operator)) {\n      throw new BadRequestException(\"operator should not be null or empty\");\n    }\n  }\n\n  private UserTokenInfo toInfo(UserToken userToken) {\n    return toInfo(userToken, new Date());\n  }","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/UserTokenService.java#L382-L418","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — assuming maxExpireDays=90\nCalendar cal = Calendar.getInstance();\ncal.add(Calendar.DAY_OF_YEAR, 365);\nrequest.setExpires(cal.getTime());\n// after\ncal.add(Calendar.DAY_OF_YEAR, 90);\nrequest.setExpires(cal.getTime());","handlingStrategy":"validation","validationCode":"int maxDays = portalConfig.userTokenMaxExpireDays();\nCalendar maxCal = Calendar.getInstance();\nmaxCal.add(Calendar.DAY_OF_YEAR, maxDays);\nif (request.getExpires() != null && request.getExpires().after(maxCal.getTime())) {\n    request.setExpires(maxCal.getTime()); // or throw\n}\nuserTokenService.createToken(request, operator);","typeGuard":"static boolean isExpiryWithinMax(Date expires, int maxDays) {\n    if (expires == null) return true;\n    Calendar maxCal = Calendar.getInstance();\n    maxCal.add(Calendar.DAY_OF_YEAR, maxDays);\n    return !expires.after(maxCal.getTime());\n}","tryCatchPattern":"try {\n    userTokenService.createToken(request, operator);\n} catch (BadRequestException e) {\n    if (e.getMessage().contains(\"exceeds max allowed days\")) {\n        return Response.status(400).entity(\"Expiry exceeds the configured maximum lifetime\").build();\n    }\n    throw e;\n}","preventionTips":["Use the default expiry (null) which is always within the max.","Check portalConfig.userTokenMaxExpireDays() before setting a custom expiry."],"tags":["apollo-portal","user-token","validation","configuration","bad-request"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}