{"record":{"id":"1bf6206e7e4f47bd","repo":"dromara/Sa-Token","slug":"code-30023","errorCode":"CODE_30023","errorMessage":"应用 [{client}] 推送地址无效：{_pushUrl}","messagePattern":"应用 \\[(.+?)\\] 推送地址无效：(.+?)","errorType":"exception","errorClass":"SaSsoException","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java","lineNumber":93,"sourceCode":"    /**\n     * 以数组形式写入允许的授权回调地址\n     * @param url 所有集合\n     * @return 对象自身\n     */\n    public SaSsoClientModel setAllow(String ...url) {\n        this.setAllowUrl(SaFoxUtil.arrayJoin(url));\n        return this;\n    }\n\n    /**\n     * 获取拼接 url：此 Client 端推送消息的地址\n     *\n     * @return /\n     */\n    public String splicingPushUrl() {\n        String _pushUrl = SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());\n        if ( ! SaFoxUtil.isUrl(_pushUrl)) {\n            throw new SaSsoException(\"应用 [\" + getClient() + \"] 推送地址无效：\" + _pushUrl).setCode(SaSsoErrorCode.CODE_30023);\n        }\n        return _pushUrl;\n    }\n\n\n    // get set\n\n    /**\n     * @return Client 名称标识\n     */\n    public String getClient() {\n        return client;\n    }\n\n    /**\n     * @param client Client 名称标识\n     */\n    public SaSsoClientModel setClient(String client) {","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java#L75-L111","documentation":"Thrown by SaSsoClientModel.splicingPushUrl when the merged push URL (serverUrl joined with pushUrl via SaFoxUtil.spliceTwoUrl) fails SaFoxUtil.isUrl (code 30023). SSO message push (logout/notification callbacks) needs a valid absolute URL; if the result is blank or malformed the model refuses to return it.","triggerScenarios":"Configuring a SaSsoClientModel whose pushUrl is empty/null while serverUrl is also missing or relative, or whose combined value is not a parseable absolute URL; then triggering a push (splicingPushUrl call) during SSO logout/message push.","commonSituations":"server-url not set in test environment; push-url given as a relative path '/sso/push' with no resolvable server-url; trailing configuration migration to the new SaSsoClientModel builder where the push url field was dropped; reverse proxy setups where the configured base URL lacks scheme.","solutions":["Set a complete absolute push-url, e.g. http://client.example.com/sso/push, or ensure server-url is absolute so the splice yields a valid URL","Verify both fields after builder migration: new SaSsoClientModel().setServerUrl(\"http://client.example.com\").setPushUrl(\"/sso/push\")","If push is not needed, avoid code paths that call splicingPushUrl or disable message push in SSO config"],"exampleFix":"// before\nnew SaSsoClientModel().setClient(\"client1\").setPushUrl(\"/sso/push\"); // no server-url\n// after\nnew SaSsoClientModel().setClient(\"client1\").setServerUrl(\"http://client.example.com\").setPushUrl(\"/sso/push\");","handlingStrategy":"validation","validationCode":"String merged = SaFoxUtil.spliceTwoUrl(clientModel.getServerUrl(), clientModel.getPushUrl());\nif (!SaFoxUtil.isUrl(merged)) throw new IllegalStateException(\"push url invalid, configure absolute server-url + push-url: \" + merged);","typeGuard":null,"tryCatchPattern":"try { clientModel.splicingPushUrl(); } catch (SaSsoException e) { if (e.getCode() == 30023) { log.error(\"SSO push url misconfigured for client {}\", clientModel.getClient()); disablePushUntilFixed(); return; } throw e; }","preventionTips":["Validate every SaSsoClientModel with an isUrl check at config load time","Always configure server-url as an absolute URL with scheme, even when push-url is relative"],"tags":["sso","push-url","configuration","url"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}