{"record":{"id":"00ef27fa2d4c5ad4","repo":"dromara/Sa-Token","slug":"code-30006","errorCode":"CODE_30006","errorMessage":"{result.getMsg()}","messagePattern":"\\{result\\.getMsg\\(\\)\\}","errorType":"exception","errorClass":"SaSsoException","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java","lineNumber":284,"sourceCode":"\n\t\t// 如果未登录，则无需注销\n\t\tif( ! stpLogic.isLogin()) {\n\t\t\treturn _ssoLogoutBack(req, res);\n\t\t}\n\n\t\t// 向 sso-server 认证中心推送消息：单点注销\n\t\tSaLogoutParameter logoutParameter = stpLogic.createSaLogoutParameter();\n\t\tif(singleDeviceIdLogout) {\n\t\t\tlogoutParameter.setDeviceId(stpLogic.getLoginDeviceId());\n\t\t}\n\t\tObject loginId = stpLogic.getLoginId();\n\t\tObject centerId = ssoClientTemplate.strategy.convertLoginIdToCenterId.run(loginId);\n\t\tSaSsoMessage message = ssoClientTemplate.buildSignoutMessage(centerId, logoutParameter);\n\t\tSaResult result = ssoClientTemplate.pushMessageAsSaResult(message);\n\n\t\t// 如果 sso-server 响应的状态码非200，代表业务失败，将回应的 msg 字段作为异常抛出\n\t\tif(result.getCode() == null || SaResult.CODE_SUCCESS != result.getCode()) {\n\t\t\tthrow new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30006);\n\t\t}\n\n\t\t// 极端场景下，sso-server 中心的单点注销可能并不会通知到当前 client 端，所以这里需要再补一刀\n\t\tif(stpLogic.isLogin()) {\n\t\t\tstpLogic.logout(loginId, logoutParameter);\n\t\t}\n\t\treturn _ssoLogoutBack(req, res);\n\t}\n\n\t/**\n\t * 封装：校验ticket，取出loginId，如果 ticket 无效则抛出异常 （适用于模式二或模式三）\n\t *\n\t * @param ticket ticket码\n\t * @return SaCheckTicketResult\n\t */\n\tpublic SaCheckTicketResult checkTicket(String ticket) {\n\t\treturn checkTicket(ticket, null);\n\t}","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java#L266-L302","documentation":"Thrown during SSO single-sign-out on the client side: the client pushed a signout message to the sso-server via pushMessageAsSaResult, and the server's HTTP response did not carry code 200. The exception message is the server's own msg field, so the root cause text comes from the remote server.","triggerScenarios":"User logs out on an SSO client; SaSsoClientProcessor builds a signout message and posts it to the sso-server's /sso/signout endpoint; the server returns a non-200 SaResult (e.g. ticket/session invalid, signature failure, server misconfigured) and the client rethrows the server's msg with code CODE_30006.","commonSituations":"sso-server down or returning an error page (HTML parsed as SaResult); secret-key mismatch between client and server so message checking fails on the server; network/proxy issues returning 404/500; the session already expired on the server.","solutions":["Check the sso-server logs at the moment of the logout push — the thrown msg is the server-side error reason","Verify sa-token.sso.secret-key (and is-same-token / message signature config) matches on client and server","Confirm the server's sso endpoint URL (sa-token.sso.server-url / api-url) is correct and reachable, not behind an auth filter that returns 401/404"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    ssoClientTemplate.ssoLogout(...);\n} catch (SaSsoException e) {\n    if(SaSsoErrorCode.CODE_30006 == e.getCode()) {\n        // server push failed; fall back to local logout so the user is not stuck\n        stpLogic.logout(loginId);\n    }\n}","preventionTips":["Keep secret-key and endpoints consistent across SSO peers","Monitor server-side logs for the original msg text carried by this exception"],"tags":["sa-token","sso","logout","remote-call"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}