alibaba/nacos · error · AccessException

Code: %d, Message: %s.

Error message

Code: %d, Message: %s.

What it means

Thrown by AbstractWebAuthFilter (servlet/web auth filter) at the authority-check stage. After identity validation passes, the filter calls protocolAuthService.validateAuthority(...) with the parsed resource and action (READ/WRITE); if the authenticated identity lacks permission, AuthResult.isSuccess() is false and an AccessException is thrown carrying result.format() (a 'Code: %d, Message: %s.' formatted string). This is an authorization (not authentication) denial on an HTTP request.

Source

Thrown at core/src/main/java/com/alibaba/nacos/core/auth/AbstractWebAuthFilter.java:144

            requestContext.getAuthContext().setAuthResult(result);
            if (!result.isSuccess()) {
                throw new AccessException(result.format());
            }
            if (isIdentityOnlyApi(secured)) {
                if (Loggers.AUTH.isDebugEnabled()) {
                    Loggers.AUTH.debug(
                        "API is identity only, skip validate authority, request: {} {}",
                        req.getMethod(),
                        req.getRequestURI());
                }
                chain.doFilter(request, response);
                return;
            }
            String action = secured.action().toString();
            result = protocolAuthService.validateAuthority(identityContext,
                new Permission(resource, action));
            if (!result.isSuccess()) {
                throw new AccessException(result.format());
            }
            chain.doFilter(request, response);
        } catch (Exception e) {
            handleFilterException(req, resp, method, e);
        }
    }
    
    private void handleFilterException(HttpServletRequest req, HttpServletResponse resp,
        Method method, Exception e)
        throws IOException, ServletException {
        if (e instanceof AccessException accessException) {
            if (Loggers.AUTH.isDebugEnabled()) {
                Loggers.AUTH.debug("access denied, request: {} {}, reason: {}", req.getMethod(),
                    req.getRequestURI(),
                    accessException.getErrMsg());
            }
            writeAccessDeniedResponse(resp, method, accessException.getErrMsg());
            return;

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Grant the user/role the required permission (resource + action) in the auth system.
  2. Verify the correct namespace/resource is being targeted — permissions are namespace-scoped.
  3. Check that the token's identity maps to a user with the needed role.
  4. If using server-identity bypass, confirm the identity header matches.

Example fix

// No code fix — this is an access-control decision. Resolve by granting permission:
// Via Nacos console or API:
//   POST /v3/auth/permission  { role: 'developer', resource: 'namespaceId:*:s:*', action: 'w' }
// Then retry the request.
Defensive patterns

Strategy: try-catch

Try / catch

// Client side: detect 403 from the web auth filter and surface a permission message.
try {
  await fetch(url, { headers: authHeaders() });
} catch (e) {
  // HTTP 403 bodies carry the AccessException formatted message
}
// Or inspect response.status === 403 and read the Result failure message.

Prevention

When it happens

Trigger: An authenticated HTTP request (valid token/identity) to a @Secured endpoint where the user/role does not have the required permission for the resource+action. E.g. a read-only user POSTing to /v3/admin/ns/service, or a user without CONFIG write permission publishing a config. The identity check at line 128 passed; this is purely the authority check at line 144.

Common situations: Role-based permission missing for the resource namespace. User authenticated but not granted the specific action. Permission record deleted or mis-scoped. New API added without granting the role access.

Related errors


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