{"record":{"id":"7466bc6301cf79f8","repo":"alibaba/canal","slug":"nul-secondary-logpositionmanager","errorCode":null,"errorMessage":"nul secondary LogPositionManager","messagePattern":"nul secondary LogPositionManager","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/index/FailbackLogPositionManager.java","lineNumber":29,"sourceCode":" * 实现基于failover查找的机制完成meta的操作\n *\n * <pre>\n * 应用场景：比如针对内存buffer，出现HA切换，先尝试从内存buffer区中找到lastest position，如果不存在才尝试找一下meta里消费的信息\n * </pre>\n */\npublic class FailbackLogPositionManager extends AbstractLogPositionManager {\n\n    private final static Logger           logger = LoggerFactory.getLogger(FailbackLogPositionManager.class);\n\n    private final CanalLogPositionManager primary;\n    private final CanalLogPositionManager secondary;\n\n    public FailbackLogPositionManager(CanalLogPositionManager primary, CanalLogPositionManager secondary){\n        if (primary == null) {\n            throw new NullPointerException(\"nul primary LogPositionManager\");\n        }\n        if (secondary == null) {\n            throw new NullPointerException(\"nul secondary LogPositionManager\");\n        }\n\n        this.primary = primary;\n        this.secondary = secondary;\n    }\n\n    @Override\n    public void start() {\n        super.start();\n\n        if (!primary.isStart()) {\n            primary.start();\n        }\n\n        if (!secondary.isStart()) {\n            secondary.start();\n        }\n    }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/index/FailbackLogPositionManager.java#L11-L47","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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.","Ensure any dependencies the secondary needs (e.g. zkClient for ZooKeeperLogPositionManager) are themselves non-null and started.","If you do not need a failback, switch the position manager type to a non-failback implementation (Memory/ZooKeeper/Meta) instead of Failback."],"exampleFix":"// before\nlogPositionManager = new FailbackLogPositionManager(primary, secondary); // secondary == null\n\n// after\nif (primary == null || secondary == null) {\n    throw new IllegalArgumentException(\"Failback needs both primary and secondary\");\n}\nlogPositionManager = new FailbackLogPositionManager(primary, secondary);","handlingStrategy":"validation","validationCode":"if (primary == null || secondary == null) {\n    throw new IllegalArgumentException(\"primary and secondary LogPositionManager are required\");\n}\nnew FailbackLogPositionManager(primary, secondary);","typeGuard":"// java.util.function.Predicate style guard\nboolean hasBothManagers(CanalLogPositionManager p, CanalLogPositionManager s) {\n    return p != null && s != null;\n}","tryCatchPattern":null,"preventionTips":["Inject both primary and secondary LogPositionManager beans via constructor injection so Spring fails fast on missing beans.","Unit-test position-manager wiring with non-null delegates before deploy.","Never call the constructor inside a try/catch that swallows the NPE - fix the null source instead."],"tags":["canal","log-position-manager","null-check","configuration","constructor"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}