{"record":{"id":"c37f45106a0749cd","repo":"alibaba/Sentinel","slug":"unexpected-status","errorCode":"UNEXPECTED_STATUS","errorMessage":"unexpected status","messagePattern":"unexpected status","errorType":"exception","errorClass":"SentinelClusterException","httpStatus":null,"severity":"error","filePath":"sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/cluster/client/NettyTransportClient.java","lineNumber":231,"sourceCode":"            throw new SentinelClusterException(ClusterErrorMessages.BAD_REQUEST);\n        }\n        int xid = getCurrentId();\n        try {\n            request.setId(xid);\n\n            channel.writeAndFlush(request);\n\n            ChannelPromise promise = channel.newPromise();\n            TokenClientPromiseHolder.putPromise(xid, promise);\n\n            if (!promise.await(ClusterClientConfigManager.getRequestTimeout())) {\n                throw new SentinelClusterException(ClusterErrorMessages.REQUEST_TIME_OUT);\n            }\n\n            SimpleEntry<ChannelPromise, ClusterResponse> entry = TokenClientPromiseHolder.getEntry(xid);\n            if (entry == null || entry.getValue() == null) {\n                // Should not go through here.\n                throw new SentinelClusterException(ClusterErrorMessages.UNEXPECTED_STATUS);\n            }\n            return entry.getValue();\n        } finally {\n            TokenClientPromiseHolder.remove(xid);\n        }\n    }\n\n    private int getCurrentId() {\n        int pre, next;\n        do {\n            pre = idGenerator.get();\n            next = pre >= MAX_ID ? MIN_ID : pre + 1;\n        } while (!idGenerator.compareAndSet(pre, next));\n        return next;\n    }\n\n    /*public CompletableFuture<ClusterResponse> sendRequestAsync(ClusterRequest request) {\n        // Uncomment this when min target JDK is 1.8.","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/cluster/client/NettyTransportClient.java#L213-L249","documentation":"After a successful promise.await in sendRequest(), the code looks up the completed entry by xid in TokenClientPromiseHolder. If the entry or its response value is null, it throws SentinelClusterException(UNEXPECTED_STATUS) with the source comment 'Should not go through here'. It fires when the promise completed (usually exceptionally, e.g. channel closed) without a response ever being stored — a rare internal inconsistency path.","triggerScenarios":"The channel fails/closes after writeAndFlush but before the response arrives — the promise is failed (completing the await) while TokenClientHandler never put a ClusterResponse for that xid; concurrent disconnect racing an in-flight request.","commonSituations":"Token server or connection dropping mid-request; Netty pipeline exceptions; seen intermittently during token-server restarts or network flaps.","solutions":["Treat like other cluster failures: catch SentinelClusterException and degrade to local flow control","Check client-server connectivity and TokenClientHandler logs for the underlying channel error","Upgrade Sentinel — later versions hardened promise failure handling in NettyTransportClient/TokenClientPromiseHolder","Ensure only one event loop touches the promise holder (no custom client modifications)"],"exampleFix":"// before\nTokenResult r = tokenService.requestToken(name, count, prioritized);\n\n// after\nTokenResult r;\ntry {\n    r = tokenService.requestToken(name, count, prioritized);\n} catch (SentinelClusterException e) {\n    logger.warn(\"cluster request failed: {}\", e.getMessage());\n    r = new TokenResult(TokenResultStatus.FAIL); // local fallback decision\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    result = tokenService.requestToken(name, count, prioritized);\n} catch (SentinelClusterException e) {\n    logger.warn(\"cluster transport anomaly: {}\", e.getMessage());\n    result = localModeRequest(name, count);\n}","preventionTips":["Treat UNEXPECTED_STATUS as a connection-churn symptom: check TokenClientHandler logs","Keep the Sentinel version current — this 'should not happen' path has been hardened over releases","Degrade to local flow control on any SentinelClusterException in the request path"],"tags":["cluster","netty","internal-error","connection-reset","race-condition"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}