MyCATApache/Mycat-Server · error · IllegalStateException
IncrSequenceZKHandler should be loaded first!
Error message
IncrSequenceZKHandler should be loaded first!
What it means
fetchNextPeriod() requires per-thread state (the InterProcessSemaphoreMutex) that is only populated by handle() during load()/initializeZK(). If the mutex ThreadLocal is null when fetchNextPeriod runs, the ZK handler was never initialized on this thread, so it throws IllegalStateException. Without the lock it is unsafe to fetch a new ID period from ZooKeeper.
Solutions
- Ensure IncrSequenceZKHandler.load() is invoked (and succeeds) before any nextId()/fetchNextPeriod call
- Verify ZK connectivity and ZkConfig cluster ID so initializeZK() completes instead of failing silently inside load()'s catch block
- Call threadLocalLoad() on the current thread before using the handler if worker threads are involved
Example fix
// before
IncrSequenceZKHandler.getInstance().nextId("ORDERS"); // handler never loaded
// after
IncrSequenceZKHandler handler = IncrSequenceZKHandler.getInstance();
handler.load();
long id = handler.nextId("ORDERS"); Defensive patterns
Strategy: validation
Validate before calling
if (!zkHandlerInitialized) {
handler.load(); // must succeed before any nextId() call
}
// confirm load() did not fail: initializeZK errors are only logged, not rethrown Try / catch
try {
long id = handler.nextId(prefixName);
} catch (IllegalStateException e) {
LOGGER.error("ZK sequence handler not initialized on this thread", e);
handler.threadLocalLoad();
long id = handler.nextId(prefixName);
} Prevention
- Always call load() at startup and verify ZK connectivity — load() swallows initializeZK() exceptions
- Check startup logs for 'Error caught while initializing ZK'
- Initialize handler state on every worker thread via threadLocalLoad()
When it happens
Trigger: Calling fetchNextPeriod (directly or via handle/getParaValMap -> threadLocalLoad) on a thread where IncrSequenceZKHandler.load() or initializeZK() was never run — e.g. ZkConfig/ZK URL missing so load() failed, or load() was skipped entirely.
Common situations: ZooKeeper unavailable at startup: load() catches the exception and only logs it, so the handler instance exists but was never initialized; calling nextId() before load(); using the handler from a worker thread that never ran threadLocalLoad().
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- can't find myid properties file
- clusterId and zkURL and myid must not be null or empty!
- Have already allocated a maximum of
- Writer already closed. Cannot be reopened.
- MySQL replication stream is already open
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/6ab5931cddf0acdd.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/sequence/handler/IncrSequenceZKHandler.java:173
Map<String, Map<String, String>> tableParaValMap = tableParaValMapThreadLocal.get();
if (tableParaValMap == null) {
try {
threadLocalLoad();
} catch (Exception e) {
LOGGER.error("Error caught while loding configuration within current thread:" + e.getCause());
}
tableParaValMap = tableParaValMapThreadLocal.get();
}
Map<String, String> paraValMap = tableParaValMap.get(prefixName);
return paraValMap;
}
@Override
public Boolean fetchNextPeriod(String prefixName) {
InterProcessSemaphoreMutex interProcessSemaphoreMutex = interProcessSemaphoreMutexThreadLocal.get();
try {
if (interProcessSemaphoreMutex == null) {
throw new IllegalStateException("IncrSequenceZKHandler should be loaded first!");
}
interProcessSemaphoreMutex.acquire();
Map<String, Map<String, String>> tableParaValMap = tableParaValMapThreadLocal.get();
if (tableParaValMap == null) {
throw new IllegalStateException("IncrSequenceZKHandler should be loaded first!");
}
Map<String, String> paraValMap = tableParaValMap.get(prefixName);
if (paraValMap == null) {
throw new IllegalStateException("IncrSequenceZKHandler should be loaded first!");
}
if (paraValMap.get(prefixName + KEY_MAX_NAME) == null) {
paraValMap.put(prefixName + KEY_MAX_NAME, props.getProperty(prefixName + KEY_MAX_NAME));
}
if (paraValMap.get(prefixName + KEY_MIN_NAME) == null) {
paraValMap.put(prefixName + KEY_MIN_NAME, props.getProperty(prefixName + KEY_MIN_NAME));
}
if (paraValMap.get(prefixName + KEY_CUR_NAME) == null) {
paraValMap.put(prefixName + KEY_CUR_NAME, props.getProperty(prefixName + KEY_CUR_NAME));View on GitHub (pinned to 65f8d8beb7)