alibaba/nacos · error · NacosApiException

20002

20002

Error message

Request header `Request-Module` must be `AI`.

What it means

Stateful Agent HTTP operations (register, deregister, heartbeat) require the 'Request-Module' HTTP header to be exactly 'AI' (case-insensitive). The AgentHttpClientLifecycleService.validateStatefulHeaders method (line 230) throws this NacosApiException (code 20002, INVALID_PARAM) when the header is missing, blank, or set to any other module name. This routes the request to the correct AI module handler.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/runtime/AgentHttpClientLifecycleService.java:231

            attributes == null ? null : attributes.getClientAttribute(IDENTITY_ATTRIBUTE);
        if (!Objects.equals(boundIdentity, VisibilityHelper.resolveCurrentIdentity())) {
            throw accessDenied("HTTP Client identity does not match its initial binding.");
        }
    }
    
    private HttpConnectionBasedClient getClient(String externalClientId) {
        String internalClientId =
            HttpConnectionBasedClient.getInternalClientId(externalClientId);
        Client client = clientManager.getClient(internalClientId);
        return client instanceof HttpConnectionBasedClient
            ? (HttpConnectionBasedClient) client : null;
    }
    
    private void validateStatefulHeaders(String externalClientId, String requestModule)
        throws NacosApiException {
        validateExternalClientId(externalClientId);
        if (!Constants.AI.AI_MODULE.equalsIgnoreCase(requestModule)) {
            throw new NacosApiException(NacosException.INVALID_PARAM,
                ErrorCode.PARAMETER_VALIDATE_ERROR,
                "Request header `" + HttpHeaderConsts.REQUEST_MODULE + "` must be `AI`.");
        }
    }
    
    private void validateExternalClientId(String externalClientId) throws NacosApiException {
        if (StringUtils.isBlank(externalClientId)
            || externalClientId.length() > MAX_EXTERNAL_CLIENT_ID_LENGTH
            || !EXTERNAL_CLIENT_ID_PATTERN.matcher(externalClientId).matches()) {
            throw new NacosApiException(NacosException.INVALID_PARAM,
                ErrorCode.PARAMETER_VALIDATE_ERROR,
                "Request header `" + ClientConstants.HTTP_CLIENT_ID_HEADER
                    + "` must match `[A-Za-z0-9._:-]+` and contain 1 to 256 characters.");
        }
    }
    
    private ClientLivenessInfo buildLivenessInfo() {
        // These are the effective fixed intervals used by HttpConnectionBasedClientManager.

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Add the HTTP header 'Request-Module: AI' to every stateful Agent HTTP request.
  2. If using an SDK, ensure you are using the AI agent client, not the Naming client.
  3. Verify that no intermediary (load balancer, API gateway) strips the Request-Module header.

Example fix

// before (curl)
curl -X POST http://host/v3/admin/ai/agent/endpoints -H 'X-Nacos-Client-Id: my-client' ...
// after
curl -X POST http://host/v3/admin/ai/agent/endpoints -H 'X-Nacos-Client-Id: my-client' -H 'Request-Module: AI' ...
Defensive patterns

Strategy: validation

Validate before calling

if (!"AI".equalsIgnoreCase(requestModule)) {
    throw new IllegalArgumentException("Request-Module header must be AI");
}

Type guard

public static boolean isValidAiRequestModule(String header) {
    return "AI".equalsIgnoreCase(header);
}

Try / catch

try {
    service.register(clientId, requestModule, batch);
} catch (NacosApiException e) {
    if (e.getErrCode() == 20002 && e.getMessage().contains("Request-Module")) {
        // set the header to AI and retry
    }
    throw e;
}

Prevention

When it happens

Trigger: Sending an HTTP request to an Agent endpoint registration/deregistration/heartbeat API without the 'Request-Module: AI' header, or with it set to 'Naming', 'Config', or another value.

Common situations: SDK or curl command that omits the header; a proxy or gateway that strips custom headers; using a Naming client instead of the AI agent client; header name typo (e.g. 'RequestModule' without the hyphen).

Related errors


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