dromara/Sa-Token · error · SaSsoException

CODE_30021

CODE_30021

Error message

未能找到消息处理器: {type}

What it means

Thrown by SaSsoMessageHolder.handleMessage when no SaSsoMessageHandle is registered in messageHandleMap for message.getType(). The holder dispatches SSO messages by type string; an unregistered type means this node cannot process the message (e.g. a newer message type sent by a peer).

Source

Thrown at sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java:104

     * 获取指定类型的消息处理器
     *
     * @param type /
     */
    public SaSsoMessageHandle getHandle(String type) {
        return messageHandleMap.get(type);
    }

    /**
     * 处理指定消息
     *
     * @param ssoTemplate /
     * @param message /
     * @return 处理结果
     */
    public Object handleMessage(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
        SaSsoMessageHandle handle = messageHandleMap.get(message.getType());
        if(handle == null) {
            throw new SaSsoException("未能找到消息处理器: " + message.getType()).setCode(SaSsoErrorCode.CODE_30021);
        }
        return handle.handle(ssoTemplate, message);
    }

}

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Register a handler for the type before it can arrive: messageHolder.putMessageHandle("the-type", ssoTemplate -> ...)
  2. Align sa-token versions on server and client so both know the same message types
  3. Check for typos between setType(...) on the sender and the key used when registering the handler

Example fix

// before
SaSsoMessage msg = new SaSsoMessage().setType("custom-notify");
clientTemplate.messageHolder.handleMessage(ssoTemplate, msg); // CODE_30021

// after
clientTemplate.messageHolder.putMessageHandle("custom-notify", (ssoTemplate, message) -> {
    // handle it
    return SaResult.ok();
});
clientTemplate.messageHolder.handleMessage(ssoTemplate, msg);
Defensive patterns

Strategy: validation

Validate before calling

if(ssoTemplate.messageHolder.getMessageHandle(message.getType()) == null) {
    // unknown type: drop or register handler before dispatch
}

Try / catch

try { holder.handleMessage(tpl, msg); } catch (SaSsoException e) { if(SaSsoErrorCode.CODE_30021 == e.getCode()) { /* respond 'unsupported message type' */ } }

Prevention

When it happens

Trigger: sso-server pushes a message of a type this client never registered (e.g. a new message type introduced in a newer sa-token version), or a custom type string was set on the message but the corresponding handler was not added via the holder's registration API.

Common situations: Version mismatch between sso-server and sso-client (server newer than client); typo in the custom message type string; forgetting to register a custom SaSsoMessageHandle before receiving that message type.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/976b3ba678f704db. Report an issue: GitHub.