alibaba/nacos · warning · NacosException
-503
-503
Error message
More than client-side current limit threshold
What it means
Thrown with code -503 (CLIENT_OVER_THRESHOLD) by ClientWorker.requestProxy when the client-side rate limiter (Limiter) rejects the request. Limiter uses a per-key Guava RateLimiter defaulting to 5 QPS (overridable via the 'limitTime' property) keyed on the request class + JSON body. When tryAcquire fails within 1000ms, the request is rejected to protect the client/server from config-query storms.
Source
Thrown at client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java:1387
Response requestProxy(RpcClient rpcClientInner, Request request) throws NacosException {
return requestProxy(rpcClientInner, request, requestTimeout);
}
private Response requestProxy(RpcClient rpcClientInner, Request request, long timeoutMills)
throws NacosException {
try {
request.putAllHeader(super.getSecurityHeaders(resourceBuild(request)));
request.putAllHeader(super.getCommonHeader());
} catch (Exception e) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
}
JsonObject asJsonObjectTemp = new Gson().toJsonTree(request).getAsJsonObject();
asJsonObjectTemp.remove("headers");
asJsonObjectTemp.remove("requestId");
boolean limit = Limiter.isLimit(request.getClass() + asJsonObjectTemp.toString());
if (limit) {
throw new NacosException(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold");
}
Response response;
if (timeoutMills < 0) {
response = rpcClientInner.request(request);
} else {
response = rpcClientInner.request(request, timeoutMills);
}
// If the 403 login operation is triggered, refresh the accessToken of the client
if (response.getErrorCode() == ConfigQueryResponse.NO_RIGHT) {
reLogin();
}
return response;
}
private RequestResource resourceBuild(Request request) {
if (request instanceof ConfigQueryRequest) {
String tenant = ((ConfigQueryRequest) request).getTenant();View on GitHub (pinned to 9b989acdf1)
Solutions
- Reduce the getConfig/publishConfig call rate to stay under 5 QPS (batch or cache results).
- Raise the limit via the 'limitTime' system property (e.g. -DlimitTime=20) if higher throughput is intended.
- Cache config locally and use listeners for change notification instead of repeated queries.
- Investigate and remove runaway loops that issue redundant config requests.
Example fix
// before
for (int i = 0; i < 1000; i++) {
configService.getConfig(dataId, group, 5000);
}
// after
String cached = configService.getConfig(dataId, group, 5000);
configService.addListener(dataId, group, listener); // react to changes Defensive patterns
Strategy: validation
Validate before calling
// throttle getConfig calls to < 5/sec per request signature RateLimiter rl = RateLimiter.create(4.0); rl.acquire(); configService.getConfig(dataId, group, timeout);
Try / catch
try {
configService.getConfig(dataId, group, timeout);
} catch (NacosException e) {
if (e.getErrCode() == NacosException.CLIENT_OVER_THRESHOLD) {
// back off and retry with delay
Thread.sleep(500);
}
} Prevention
- Cache configs and use listeners instead of repeated getConfig.
- Raise -DlimitTime if you legitimately need higher QPS.
- Avoid tight startup loops issuing many concurrent getConfig calls.
When it happens
Trigger: Issuing getConfig/publishConfig calls faster than the client-side QPS cap (default 5/sec) for the same request signature, e.g. a tight loop calling getConfig in many threads.
Common situations: Application startup fan-out where many beans call getConfig concurrently, a retry storm, or a custom loop polling config without throttling.
Related errors
- [NACOS HTTP-GET] The maximum number of tolerable server reco
- no available server
- [NACOS HTTP-POST] The maximum number of tolerable server rec
- no available server, currentServerAddr : {currentServerAddr}
- [NACOS HTTP-DELETE] The maximum number of tolerable server r
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/8e5229544f391cc9.
Report an issue: GitHub.