MyCATApache/Mycat-Server · error

ERR_HANDLE_DATA

ERR_HANDLE_DATA

Error message

e.toString()

What it means

In NonBlockingSession.execute, when a single-node/route query handler throws during execution, the exception is logged and its toString() is sent back to the client as an ERR_HANDLE_DATA error message. The message content is whatever e.toString() yields (e.g. 'java.lang.NullPointerException ...'), not a structured error.

Solutions

  1. Read the full stack trace from the MyCat server log (logged at WARN with source and RouteResultset) — e.toString() alone hides the cause.
  2. Check backend dataNode/host connectivity (show @@heartbeat) since dead connections are the most common trigger.
  3. Retry the query; if persistent, restart the affected MyCat connection pool / backend node.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    singleNodeQuery(sql);
} catch (SQLException e) {
    if (e.getErrorCode() == 30003 /* ERR_HANDLE_DATA */) {
        log.warn("MyCat execution failed: " + e.getMessage(), e);
        checkBackendHealth();
        retryOnceWithBackoff();
    }
}

Prevention

When it happens

Trigger: Any Exception escaping SingleNodeHandler.execute() (or checkDistriTransaxAndExecute with initCount>1) during query execution on a session's single-node path.

Common situations: Backend MySQL node down or connection broken mid-query; NPE in handler code; query timeout canceling the handler; charset/protocol issues with the backend.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/3db0c5fdd8bdff5d. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/server/NonBlockingSession.java:154

            source.getListener().fireEvent(SqlExecuteStage.END);
            return;
        }
        boolean autocommit = source.isAutocommit();
        final int initCount = target.size();
        if (nodes.length == 1) {
            singleNodeHandler = new SingleNodeHandler(rrs, this);
            if (this.isPrepared()) {
                singleNodeHandler.setPrepared(true);
            }

            try {
                if(initCount > 1){
                    checkDistriTransaxAndExecute(rrs,1,autocommit);
                }else{
                    singleNodeHandler.execute();
                }
            } catch (Exception e) {
                LOGGER.warn(new StringBuilder().append(source).append(rrs).toString(), e);
                source.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, e.toString());
                source.getListener().fireEvent(SqlExecuteStage.END);
            }

        } else {

            multiNodeHandler = new MultiNodeQueryHandler(type, rrs, autocommit, this);
            if (this.isPrepared()) {
                multiNodeHandler.setPrepared(true);
            }
            try {
                if(((type == ServerParse.DELETE || type == ServerParse.INSERT || type == ServerParse.UPDATE) && !rrs.isGlobalTable() && nodes.length > 1)||initCount > 1) {
                    checkDistriTransaxAndExecute(rrs,2,autocommit);
                } else {
                    multiNodeHandler.execute();
                }
            } catch (Exception e) {
                LOGGER.warn(new StringBuilder().append(source).append(rrs).toString(), e);

View on GitHub (pinned to 65f8d8beb7)