alibaba/nacos · error · NacosApiException

PARAMETER_VALIDATE_ERROR

PARAMETER_VALIDATE_ERROR

Error message

ARD namespaceId should be passed as query parameter

What it means

ARD (Agent Registry Discovery) search/explore endpoints take namespaceId as a query parameter. resolveNamespaceId rejects a request where the query namespaceId is omitted but the request body carries a non-default namespaceId, throwing PARAMETER_VALIDATE_ERROR (HTTP 400). Only the default namespace (Constants.DEFAULT_NAMESPACE_ID) may be conveyed via the body when the query param is absent.

Source

Thrown at ai-registry-adaptor/src/main/java/com/alibaba/nacos/airegistry/controller/ArdSearchController.java:150

        if (request != null) {
            request.setNamespaceId(resolveNamespaceId(queryNamespaceId, request.getNamespaceId()));
        }
    }
    
    private void bindNamespaceId(String queryNamespaceId, ArdExploreRequest request)
        throws NacosApiException {
        if (request != null) {
            request.setNamespaceId(resolveNamespaceId(queryNamespaceId, request.getNamespaceId()));
        }
    }
    
    private String resolveNamespaceId(String queryNamespaceId, String bodyNamespaceId)
        throws NacosApiException {
        if (StringUtils.isBlank(queryNamespaceId)) {
            if (StringUtils.isNotBlank(bodyNamespaceId)
                && !com.alibaba.nacos.api.common.Constants.DEFAULT_NAMESPACE_ID
                    .equals(bodyNamespaceId)) {
                throw new NacosApiException(NacosException.INVALID_PARAM,
                    ErrorCode.PARAMETER_VALIDATE_ERROR,
                    "ARD namespaceId should be passed as query parameter");
            }
            return bodyNamespaceId;
        }
        if (StringUtils.isNotBlank(bodyNamespaceId) && !queryNamespaceId.equals(bodyNamespaceId)) {
            throw new NacosApiException(NacosException.INVALID_PARAM,
                ErrorCode.PARAMETER_VALIDATE_ERROR,
                "ARD query namespaceId should match request body namespaceId");
        }
        return queryNamespaceId;
    }
    
    /**
     * Return the versioned artifact document behind an ARD catalog entry URL.
     */
    @Since("3.3.0")
    @GetMapping("/artifacts")

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Pass the namespace as a query parameter: ?namespaceId=<your-namespace>.
  2. Or remove namespaceId from the body to target the default namespace.
  3. Keep namespaceId in exactly one place (the query string) in your client.

Example fix

// before
POST /search  body {"namespaceId":"tenant-a", ...}

// after
POST /search?namespaceId=tenant-a  body {...}
Defensive patterns

Strategy: validation

Validate before calling

// Put namespaceId in the query string, not (only) the body
String ns = StringUtils.isBlank(bodyNs) ? Constants.DEFAULT_NAMESPACE_ID : bodyNs;
URI uri = UriComponentsBuilder.fromHttpUrl(baseUrl + "/search")
        .queryParam("namespaceId", ns)
        .build().toUri();
request.setNamespaceId(null); // do not rely on body for non-default namespaces

Try / catch

try {
    ardClient.search(queryNs, request);
} catch (NacosApiException e) {
    if (e.getMessage().contains("passed as query parameter")) {
        // move namespaceId from body to the query string and retry once
        queryNs = request.getNamespaceId();
        request.setNamespaceId(null);
        return ardClient.search(queryNs, request);
    }
    throw e;
}

Prevention

When it happens

Trigger: POST to /search or /explore with no ?namespaceId= query parameter, but a JSON body whose namespaceId field is set to a custom (non-default) namespace.

Common situations: An SDK that defaults namespaceId in the body; migrating from an API that accepted body namespaceId; forgetting to append the query param while the body still carries a tenant namespace.

Related errors


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