alibaba/nacos · error · NacosException
500
500
Error message
Unknown Exception.
What it means
RpcClient.request() throws SERVER_ERROR (500) 'Unknown Exception.' when currentConnection.request() returns a non-null but effectively unusable response object — specifically null parsed into the `response` variable path. It signals the transport returned nothing usable rather than an explicit server-side error payload.
Source
Thrown at common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java:676
* @return response from server.
*/
public Response request(Request request, long timeoutMills) throws NacosException {
int retryTimes = 0;
Response response;
Throwable exceptionThrow = null;
long start = System.currentTimeMillis();
while (retryTimes <= rpcClientConfig.retryTimes() && (timeoutMills <= 0
|| System.currentTimeMillis() < timeoutMills + start)) {
boolean waitReconnect = false;
try {
if (this.currentConnection == null || !isRunning()) {
waitReconnect = true;
throw new NacosException(NacosException.CLIENT_DISCONNECT,
"Client not connected, current status:" + rpcClientStatus.get());
}
response = this.currentConnection.request(request, timeoutMills);
if (response == null) {
throw new NacosException(SERVER_ERROR, "Unknown Exception.");
}
if (response instanceof ErrorResponse) {
if (response.getErrorCode() == NacosException.UN_REGISTER) {
synchronized (this) {
waitReconnect = true;
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING,
RpcClientStatus.UNHEALTHY)) {
LoggerUtils.printIfErrorEnabled(LOGGER,
"Connection is unregistered, switch server, connectionId = {}, request = {}",
currentConnection.getConnectionId(),
request.getClass().getSimpleName());
switchServerAsync();
}
}
}
throw new NacosException(response.getErrorCode(), response.getMessage());
}View on GitHub (pinned to 9b989acdf1)
Solutions
- Enable DEBUG/ERROR logging on the RpcClient and GrpcConnection to capture the underlying future result and channel state at failure time.
- Confirm client and server gRPC/protobuf versions are compatible (mismatched stubs can yield unparseable null responses).
- Retry with backoff; this is typically transient, so increasing retryTimes and timeoutMills gives the channel time to recover.
- If persistent, capture a server-side log/thread dump to confirm the server actually produced a response payload.
Defensive patterns
Strategy: retry
Try / catch
try {
response = client.request(req, timeout);
} catch (NacosException ne) {
if (ne.getErrCode() == NacosException.SERVER_ERROR) {
// back off and retry; inspect logs for null-payload cause
} else { throw ne; }
} Prevention
- Keep client/server gRPC and protobuf versions aligned.
- Enable ERROR logging on the RPC client to capture underlying future results.
- Treat null-response failures as transient and retry with backoff.
When it happens
Trigger: The underlying connection.request() invocation returns null (e.g. gRPC future returned null Payload, or parse produced null) but did not throw. The retry loop then treats this as a transient failure and retries; after exhausting retries it surfaces 'Unknown Exception.' only on the iteration itself, with -500.
Common situations: Transient gRPC channel issues that yield a null payload without an exception (rare); a malformed or empty response from a misbehaving/older server version; interceptor chain stripping the payload; netty buffer exhaustion returning an empty frame.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/3d4f0a2ed7ec5239.
Report an issue: GitHub.