alibaba/nacos · error · HttpSessionRequiredException
session expired!
Error message
session expired!
What it means
Thrown by UserControllerV3.hasPermission() as an org.springframework.web.HttpSessionRequiredException when the request's auth context carries no IdentityContext at all — meaning the caller reached a protected user-management endpoint (e.g., password update) without an established authenticated identity. The controller catches it and responds HTTP 401 'session expired!'.
Source
Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/v3/UserControllerV3.java:228
userDetailsService.updateUserPassword(username, newPassword);
return Result.success("update user ok!");
}
private boolean hasPermission(String username, HttpServletRequest request)
throws HttpSessionRequiredException, AccessException {
if (!NacosAuthConfigHolder.getInstance().isAnyAuthEnabled()) {
return true;
}
// Fixes #13959. If the user is server identity, should not check permission.
if (isFromServerIdentity(request)) {
return true;
}
IdentityContext identityContext =
RequestContextHolder.getContext().getAuthContext().getIdentityContext();
if (identityContext == null) {
throw new HttpSessionRequiredException("session expired!");
}
NacosUser user = (NacosUser) identityContext.getParameter(AuthConstants.NACOS_USER_KEY);
if (user == null) {
user = iAuthenticationManager.authenticate(request);
if (user == null) {
throw new HttpSessionRequiredException("session expired!");
}
}
//get user form jwt need check permission
iAuthenticationManager.hasGlobalAdminRole(user);
// admin
if (user.isGlobalAdmin()) {
return true;
}
// same user
return user.getUserName().equals(username);
}
View on GitHub (pinned to 9b989acdf1)
Solutions
- Authenticate first (POST /v3/auth/login) to obtain a valid token/session and pass it on subsequent calls.
- Ensure the Authorization header (or session cookie) is sent on the request.
- If integrating server-to-server, send the server-identity header which short-circuits the check via isFromServerIdentity().
Example fix
// before curl -X PUT 'http://host/v3/auth/user/update?username=alice&newPassword=...' // -> 401 session expired! // after token=$(curl -s -X POST 'http://host/v3/auth/login' -d 'username=admin&password=...' | jq -r .data.accessToken) curl -X PUT 'http://host/v3/auth/user/update?username=alice&newPassword=...' -H "Authorization: Bearer $token"
Defensive patterns
Strategy: validation
Validate before calling
// Client-side: ensure a token is present before calling a protected endpoint.
String token = currentAccessToken();
if (StringUtils.isBlank(token)) {
throw new IllegalStateException("No auth token; login first");
}
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer " + token)
.PUT(BodyPublishers.ofString(body)).build(); Try / catch
try {
controller.updateUser(username, newPassword, response, request);
} catch (HttpSessionRequiredException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "session expired!");
} Prevention
- Always send a valid Authorization header (or session cookie) on protected endpoints.
- Refresh tokens before they expire to keep IdentityContext populated.
- For server-to-server calls, use the server-identity header to bypass the user check.
When it happens
Trigger: Calling /v3/auth/user/update (or another hasPermission-guarded endpoint) when RequestContextHolder.getContext().getAuthContext().getIdentityContext() is null — e.g., no Authorization header / session cookie, or the auth filter did not populate the context (filter ordering / disabled interceptor).
Common situations: Browser session timed out and the UI did not refresh the token; a direct API call without credentials; an auth filter misconfiguration after an upgrade that stops populating IdentityContext; server-identity header also absent.
Related errors
- Request parameter `agentSpecCard` should not be null or empt
- Request parameter `agentSpecCard` is invalid and cannot be p
- Required parameter `agentSpecCard.name` is not present.
- Request parameter `name` should not be null or empty.
- Code: %d, Message: %s.
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/427b024a1b815223.
Report an issue: GitHub.