alibaba/nacos · error · NacosRuntimeException

e.getErrMsg()

Error message

e.getErrMsg()

What it means

The recognized-failure branch of updateUserPassword: the PUT .../user password update is proxied to a peer Nacos server, and either the HTTP transport raised a NacosException or singleCheckResult saw a non-OK result. The peer's original errCode and message pass through unchanged (e.g. 403 forbidden, 400 weak password).

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserServiceRemoteImpl.java:77

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = getUser(username);
        if (null == user) {
            throw new UsernameNotFoundException(String.format("User %s not found", username));
        }
        return new NacosUserDetails(user);
    }
    
    @Override
    public void updateUserPassword(String username, String password) {
        Query query = Query.newInstance().addParam("username", username);
        Map<String, String> body = Map.of("newPassword", password);
        try {
            HttpRestResult<String> result = nacosRestTemplate.putForm(
                buildRemoteUserUrlPath(AuthConstants.USER_PATH),
                RemoteServerUtil.buildServerRemoteHeader(), query, body, String.class);
            RemoteServerUtil.singleCheckResult(result);
        } catch (NacosException e) {
            throw new NacosRuntimeException(e.getErrCode(), e.getErrMsg());
        } catch (Exception unpectedException) {
            throw new NacosRuntimeException(NacosException.SERVER_ERROR,
                unpectedException.getMessage());
        }
    }
    
    @Override
    public Page<User> getUsers(int pageNo, int pageSize, String username) {
        Query query = Query.newInstance().addParam("username", username).addParam("pageNo", pageNo)
            .addParam("pageSize", pageSize).addParam("search", "accurate");
        return getUserPageFromRemote(query);
    }
    
    @Override
    public Page<User> findUsers(String username, int pageNo, int pageSize) {
        Query query = Query.newInstance().addParam("username", username).addParam("pageNo", pageNo)
            .addParam("pageSize", pageSize).addParam("search", "blur");
        return getUserPageFromRemote(query);

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Map the propagated errCode: 403 -> align server-identity header; 400 -> meet the password policy; 5xx -> peer fault, check peer logs.
  2. Verify the username exists on the peer before updating.
  3. Retry once on transient transport errors (timeout, reset).
  4. Confirm the peer is reachable from cluster.conf.

Example fix

// before
userService.updateUserPassword(username, newPassword);

// after
try {
    userService.updateUserPassword(username, newPassword);
} catch (NacosRuntimeException e) {
    if (e.getErrCode() == 400) {
        return Result.failure(400, "password rejected by policy: " + e.getMessage());
    }
    if (e.getErrCode() == 403) {
        log.error("server-identity header rejected by peer");
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm server-identity header and username before updating.
var cfg = NacosAuthConfigHolder.getInstance().getNacosAuthConfigByScope(ApiType.OPEN_API.name());
if (cfg != null && StringUtils.isBlank(cfg.getServerIdentityKey())) {
    log.warn("server-identity blank; password update may be 403'd by peer");
}
if (userService.getUser(username) == null) {
    throw new IllegalArgumentException("cannot update password: user not found " + username);
}

Try / catch

try {
    userService.updateUserPassword(username, newPassword);
} catch (NacosRuntimeException e) {
    switch (e.getErrCode()) {
        case 400: return Result.failure(400, "password rejected: " + e.getMessage());
        case 403: log.error("server-identity rejected by peer"); break;
        default:  log.error("password update failed: code={} msg={}", e.getErrCode(), e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Updating a password when the peer returns 403 (server-identity header mismatch), 400 (new password rejected by server-side policy or user not found), or a transport timeout/connection error.

Common situations: server.identity.key/value not aligned between console and server; password policy on the peer rejecting the new value; peer node down during a password-rotation workflow.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/917e31cc7988c6fb. Report an issue: GitHub.