MyCATApache/Mycat-Server · error · RuntimeException

Unknown charsetIndex:

Error message

Unknown charsetIndex:

What it means

During the MySQL handshake, MySQLConnectionAuthenticator.processHandShakePacket reads the server's charset index from the handshake packet and maps it to a charset name via CharsetUtil.getCharset(). If the returned charset is null — the index is not present in MyCat's charset table — it throws this RuntimeException, aborting backend connection authentication.

Solutions

  1. Map the unknown charset index explicitly: add an entry to CharsetUtil's charset index table (or MyCat's charset config) for the reported index before connecting
  2. Configure the MySQL server (or the user account) to use a charset MyCat knows, e.g. SET GLOBAL character_set_server=utf8 or init_connect on the account
  3. Upgrade MyCat to a version whose CharsetUtil includes the server's collation ids
  4. Patch the code to fall back to a default charset (e.g. utf8) instead of throwing when the index is unmapped

Example fix

// before
if (charset != null) { source.setCharset(charset); } else { throw new RuntimeException("Unknown charsetIndex:" + charsetIndex); }
// after
if (charset != null) { source.setCharset(charset); } else { LOGGER.warn("Unknown charsetIndex:" + charsetIndex + ", fallback to utf8"); source.setCharset("utf8"); }
Defensive patterns

Strategy: validation

Validate before calling

int idx = serverCharsetIndex & 0xff;
if (CharsetUtil.getCharset(idx) == null) {
    throw new IllegalStateException("Server charset index " + idx + " unsupported; use a server charset MyCat knows (e.g. utf8)");
}

Try / catch

try { connect(...); } catch (RuntimeException e) { if (e.getMessage().startsWith("Unknown charsetIndex:")) { /* reconfigure server charset or fallback */ } else { throw e; } }

Prevention

When it happens

Trigger: The MySQL server sends a handshake packet whose serverCharsetIndex (serverCharsetIndex & 0xff) is not in MyCat's CharsetUtil mapping — typically a newer or unusual collation id, or a charset index for a charset MyCat does not know.

Common situations: Connecting to a newer MySQL (5.7/8.0) or MariaDB whose default collation id is absent from the old MyCat charset table; servers configured with uncommon default charsets like utf8mb4_0900_ai_ci (id 255) or gb18030; connecting through a proxy that alters the handshake.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/backend/mysql/nio/MySQLConnectionAuthenticator.java:133

			}
			throw e;
		}
	}

	private void processHandShakePacket(byte[] data) {
		// 设置握手数据包
		HandshakePacket packet= new HandshakePacket();
		packet.read(data);
		source.setHandshake(packet);
		source.setThreadId(packet.threadId);

		// 设置字符集编码
		int charsetIndex = (packet.serverCharsetIndex & 0xff);
		String charset = CharsetUtil.getCharset(charsetIndex);
		if (charset != null) {
			source.setCharset(charset);
		} else {
			throw new RuntimeException("Unknown charsetIndex:" + charsetIndex);
		}
	}

	private void auth323(byte packetId) {
		// 发送323响应认证数据包
		Reply323Packet r323 = new Reply323Packet();
		r323.packetId = ++packetId;
		String pass = source.getPassword();
		if (pass != null && pass.length() > 0) {
			byte[] seed = source.getHandshake().seed;
			r323.seed = SecurityUtil.scramble323(pass, new String(seed))
					.getBytes();
		}
		r323.write(source);
	}

}

View on GitHub (pinned to 65f8d8beb7)