alibaba/canal · error · NullPointerException

nul secondary LogPositionManager

Error message

nul secondary LogPositionManager

What it means

FailbackLogPositionManager delegates writes to a primary LogPositionManager and falls back to a secondary when the primary throws. Its constructor treats both delegates as hard dependencies: a null secondary aborts construction with a NullPointerException (note the typo "nul" in the message). Without a secondary there is nothing to fail back to, so the manager cannot be created.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/index/FailbackLogPositionManager.java:29

 * 实现基于failover查找的机制完成meta的操作
 *
 * <pre>
 * 应用场景:比如针对内存buffer,出现HA切换,先尝试从内存buffer区中找到lastest position,如果不存在才尝试找一下meta里消费的信息
 * </pre>
 */
public class FailbackLogPositionManager extends AbstractLogPositionManager {

    private final static Logger           logger = LoggerFactory.getLogger(FailbackLogPositionManager.class);

    private final CanalLogPositionManager primary;
    private final CanalLogPositionManager secondary;

    public FailbackLogPositionManager(CanalLogPositionManager primary, CanalLogPositionManager secondary){
        if (primary == null) {
            throw new NullPointerException("nul primary LogPositionManager");
        }
        if (secondary == null) {
            throw new NullPointerException("nul secondary LogPositionManager");
        }

        this.primary = primary;
        this.secondary = secondary;
    }

    @Override
    public void start() {
        super.start();

        if (!primary.isStart()) {
            primary.start();
        }

        if (!secondary.isStart()) {
            secondary.start();
        }
    }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Check the position manager wiring in instance config (CanalInstanceWithManager ~line 460) and confirm the secondary LogPositionManager bean is actually created and non-null before passing it.
  2. Ensure any dependencies the secondary needs (e.g. zkClient for ZooKeeperLogPositionManager) are themselves non-null and started.
  3. If you do not need a failback, switch the position manager type to a non-failback implementation (Memory/ZooKeeper/Meta) instead of Failback.

Example fix

// before
logPositionManager = new FailbackLogPositionManager(primary, secondary); // secondary == null

// after
if (primary == null || secondary == null) {
    throw new IllegalArgumentException("Failback needs both primary and secondary");
}
logPositionManager = new FailbackLogPositionManager(primary, secondary);
Defensive patterns

Strategy: validation

Validate before calling

if (primary == null || secondary == null) {
    throw new IllegalArgumentException("primary and secondary LogPositionManager are required");
}
new FailbackLogPositionManager(primary, secondary);

Type guard

// java.util.function.Predicate style guard
boolean hasBothManagers(CanalLogPositionManager p, CanalLogPositionManager s) {
    return p != null && s != null;
}

Prevention

When it happens

Trigger: Constructing `new FailbackLogPositionManager(primary, secondary)` (e.g. in CanalInstanceWithManager:460) where the secondary argument resolves to null. This happens when the configured secondary position manager bean/factory returns null (bad Spring config, missing zookeeper block, or a null-producing factory method).

Common situations: A canal instance is configured with `canal.instance.global.position` or a failback position strategy but the fallback (often a ZooKeeperLogPositionManager built from a missing zkClient) was never instantiated. Spring XML missing a property, or a version upgrade that renamed the secondary bean key.

Related errors


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