xuxueli/xxl-job · error · RuntimeException
Permission limit[username={}]
Error message
Permission limit[username={}] What it means
Thrown by JobGroupPermissionUtil.validJobGroupPermission as a RuntimeException when the SSO login check fails OR the logged-in user lacks permission for the target jobGroup. The message bundles a localized 'permission limit' string with the username. It guards every admin operation that touches a specific job group.
Source
Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/framework/util/JobGroupPermissionUtil.java:40
* check if has jobgroup permission
*/
public static boolean hasJobGroupPermission(LoginInfo loginInfo, int jobGroup){
if (XxlSsoHelper.hasRole(loginInfo, Consts.ADMIN_ROLE).isSuccess()) {
return true;
} else {
List<String> jobGroups = (loginInfo.getExtraInfo()!=null && loginInfo.getExtraInfo().containsKey("jobGroups"))
? StringTool.split(loginInfo.getExtraInfo().get("jobGroups"), ",") :new ArrayList<>();
return jobGroups.contains(String.valueOf(jobGroup));
}
}
/**
* valid jobGroup permission
*/
public static LoginInfo validJobGroupPermission(HttpServletRequest request, int jobGroup) {
Response<LoginInfo> loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);
if (!(loginInfoResponse.isSuccess() && hasJobGroupPermission(loginInfoResponse.getData(), jobGroup))) {
throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username="+ loginInfoResponse.getData().getUserName() +"]");
}
return loginInfoResponse.getData();
}
/**
* filter jobGroupList by permission
*/
public static List<XxlJobGroup> filterJobGroupByPermission(HttpServletRequest request, List<XxlJobGroup> jobGroupListTotal){
Response<LoginInfo> loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);
if (XxlSsoHelper.hasRole(loginInfoResponse.getData(), Consts.ADMIN_ROLE).isSuccess()) {
return jobGroupListTotal;
} else {
List<String> jobGroups = (loginInfoResponse.getData().getExtraInfo()!=null
&& loginInfoResponse.getData().getExtraInfo().get("jobGroups")!=null
)
? StringTool.split(loginInfoResponse.getData().getExtraInfo().get("jobGroups"), ",")
:new ArrayList<>();View on GitHub (pinned to e74c784f68)
Solutions
- Grant the user's identity the missing jobGroup id in the 'jobGroups' attribute (comma-separated).
- Re-authenticate / refresh the SSO session if it expired.
- Confirm the request targets a jobGroup the user actually owns; admins (ADMIN_ROLE) bypass the filter entirely.
- Ensure loginInfoResponse.getData() is non-null before permission checks to avoid an NPE masking the real cause.
Example fix
// before: user has jobGroups "1,2" but request targets jobGroup 3 // grant jobGroup 3 to the user, or call as an ADMIN_ROLE user // after: ensure permission is held before invoking the protected action LoginInfo info = JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify login + permission before invoking the protected action
Response<LoginInfo> r = XxlSsoHelper.loginCheckWithAttr(request);
if (r.isSuccess() && r.getData() != null
&& JobGroupPermissionUtil.hasJobGroupPermission(r.getData(), jobGroup)) {
// proceed
} else {
log.warn("denied: user lacks jobGroup {}", jobGroup);
} Try / catch
try {
LoginInfo info = JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);
} catch (RuntimeException e) {
// permission/login failure; surface HTTP 403 to the caller
log.warn("permission denied: {}", e.getMessage());
throw new org.springframework.web.server.ResponseStatusException(org.springframework.http.HttpStatus.FORBIDDEN);
} Prevention
- Grant the user's 'jobGroups' attribute the ids they must operate on.
- Handle SSO session expiry with a re-auth redirect rather than letting it throw.
- Null-check loginInfoResponse.getData() before relying on it.
When it happens
Trigger: Calling validJobGroupPermission(request, jobGroup) when loginCheckWithAttr reports failure, or when the user's 'jobGroups' extra-info list does not contain the requested jobGroup id. Triggered on protected admin endpoints (start/stop/trigger/log/etc. per job group).
Common situations: A non-admin user (no ADMIN_ROLE) attempts to operate on a job group they were not granted; SSO session expired so loginCheck returns non-success; misconfiguration of the user's jobGroups attribute in the identity store; the jobGroup id in the request does not match any granted group.
Related errors
- xxl-job executor accessToken empty.
- Hour values must be between 0 and 23
- Day of month values must be between 1 and 31
- Month values must be between 1 and 12
- Start year must be less than stop year
AI-assisted analysis of xuxueli/xxl-job@e74c784f68 (2026-08-14).
Data as JSON: /api/errors/ceb5aa15808e0323.
Report an issue: GitHub.