alibaba/canal · error · CanalException

unsupport indexMode for {}

Error message

unsupport indexMode for {}

What it means

The terminal else-branch in initLogPositionManager() (CanalInstanceWithManager.java:461-462): thrown when IndexMode is none of MEMORY, ZOOKEEPER, MIXED, META, or MEMORY_META_FAILBACK. The IndexMode enum defines exactly those five values and the standard parser rejects unknown names earlier, so this branch is effectively unreachable on stock canal — it is a defensive fallback for a future enum constant lacking a manager implementation.

Source

Thrown at instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/CanalInstanceWithManager.java:462

        if (indexMode.isMemory()) {
            logPositionManager = new MemoryLogPositionManager();
        } else if (indexMode.isZookeeper()) {
            logPositionManager = new ZooKeeperLogPositionManager(getZkclientx());
        } else if (indexMode.isMixed()) {
            MemoryLogPositionManager memoryLogPositionManager = new MemoryLogPositionManager();
            ZooKeeperLogPositionManager zooKeeperLogPositionManager = new ZooKeeperLogPositionManager(getZkclientx());
            logPositionManager = new PeriodMixedLogPositionManager(memoryLogPositionManager,
                zooKeeperLogPositionManager,
                1000L);
        } else if (indexMode.isMeta()) {
            logPositionManager = new MetaLogPositionManager(metaManager);
        } else if (indexMode.isMemoryMetaFailback()) {
            MemoryLogPositionManager primary = new MemoryLogPositionManager();
            MetaLogPositionManager secondary = new MetaLogPositionManager(metaManager);

            logPositionManager = new FailbackLogPositionManager(primary, secondary);
        } else {
            throw new CanalException("unsupport indexMode for " + indexMode);
        }

        logger.info("init logPositionManager end! \n\t load CanalLogPositionManager:{}", logPositionManager.getClass()
            .getName());

        return logPositionManager;
    }

    protected void startEventParserInternal(CanalEventParser eventParser, boolean isGroup) {
        if (eventParser instanceof AbstractEventParser) {
            AbstractEventParser abstractEventParser = (AbstractEventParser) eventParser;
            abstractEventParser.setAlarmHandler(getAlarmHandler());
        }

        super.startEventParserInternal(eventParser, isGroup);
    }

    private int getGroupSize() {

View on GitHub (pinned to 87be50e876)

Solutions

  1. On a fork, give every IndexMode constant a branch in initLogPositionManager (or revert the enum).
  2. On stock canal, confirm canal.instance.indexMode is one of MEMORY/ZOOKEEPER/MIXED/META/MEMORY_META_FAILBACK.
  3. For mocked CanalParameter in tests, return IndexMode.MEMORY.
Defensive patterns

Strategy: validation

Validate before calling

CanalParameter.IndexMode m = parameters.getIndexMode();
if (!(m.isMemory() || m.isZookeeper() || m.isMixed() || m.isMeta() || m.isMemoryMetaFailback())) {
    throw new IllegalArgumentException("Unsupported canal.instance.indexMode: " + m);
}

Prevention

When it happens

Trigger: A new IndexMode constant is added without a branch in initLogPositionManager, or a custom CanalParameter returns an IndexMode whose is*() methods all return false. With stock canal no configuration string reaches this line because the enum parse would fail first.

Common situations: Practically unseen on stock canal; only on forks extending IndexMode or via reflection-injected test parameters. A live occurrence implies a customized build.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/b36ad45c0385a95f. Report an issue: GitHub.