{"record":{"id":"52dfaaabaed8642f","repo":"alibaba/canal","slug":"position-timestamp-is-empty","errorCode":null,"errorMessage":"position timestamp is empty!","messagePattern":"position timestamp is empty!","errorType":"exception","errorClass":"PositionNotFoundException","httpStatus":null,"severity":"critical","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/rds/RdsLocalBinlogEventParser.java","lineNumber":61,"sourceCode":"    public void start() throws CanalParseException {\n        try {\n            Assert.notNull(accesskey);\n            Assert.notNull(secretkey);\n            Assert.notNull(instanceId);\n            Assert.notNull(url);\n            Assert.notNull(directory);\n\n            if (endTime == null) {\n                endTime = System.currentTimeMillis();\n            }\n\n            EntryPosition entryPosition = findStartPosition(null);\n            if (entryPosition == null) {\n                throw new PositionNotFoundException(\"position not found!\");\n            }\n            Long startTimeInMill = entryPosition.getTimestamp();\n            if (startTimeInMill == null || startTimeInMill <= 0) {\n                throw new PositionNotFoundException(\"position timestamp is empty!\");\n            }\n\n            startTime = startTimeInMill;\n            List<BinlogFile> binlogFiles = RdsBinlogOpenApi.listBinlogFiles(url,\n                accesskey,\n                secretkey,\n                instanceId,\n                new Date(startTime),\n                new Date(endTime));\n            if (binlogFiles.isEmpty()) {\n                throw new CanalParseException(\"start timestamp : \" + startTimeInMill + \" binlog files is empty\");\n            }\n\n            binlogDownloadQueue = new BinlogDownloadQueue(binlogFiles, batchFileSize, directory);\n            binlogDownloadQueue.silenceDownload();\n            needWait = true;\n            // try to download one file,use to test server id\n            binlogDownloadQueue.tryOne();","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/rds/RdsLocalBinlogEventParser.java#L43-L79","documentation":"Thrown as PositionNotFoundException by RdsLocalBinlogEventParser.start() when the start position IS found (non-null) but its timestamp field is null or <= 0. The timestamp is needed to determine the time range for querying RDS binlog backup files.","triggerScenarios":"findStartPosition returns an EntryPosition object, but getTimestamp() returns null or a value <= 0. This happens when the persisted position lacks timestamp metadata — e.g., it was created by a parser that only recorded journal name and offset without a server timestamp.","commonSituations":"Position was persisted by an older canal version or different parser type that did not populate the timestamp field; position data was manually edited or corrupted; migration from a different position format that dropped the timestamp.","solutions":["Clear the existing position data and re-seed it with a valid timestamp matching a known binlog event time.","If using a custom LogPositionManager, ensure EntryPosition.setTimestamp() is called with a valid epoch millisecond value.","Upgrade the position data to include timestamp, or manually patch the stored position JSON/XML.","As a last resort, delete the position and start fresh with a configured start time."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before starting, validate the position has a timestamp\nEntryPosition pos = logPositionManager.getLatestIndexBy(destination);\nif (pos != null && (pos.getTimestamp() == null || pos.getTimestamp() <= 0)) {\n    pos.setTimestamp(System.currentTimeMillis() - 86400000L); // set to yesterday\n    logPositionManager.persistLogPosition(destination, buildLogPosition(pos));\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.start();\n} catch (PositionNotFoundException e) {\n    if (e.getMessage().contains(\"timestamp is empty\")) {\n        // patch the position with a valid timestamp and retry\n    }\n}","preventionTips":["Ensure positions are persisted with a valid epoch-millisecond timestamp.","When migrating position data, preserve the timestamp field.","Audit position data for null/zero timestamps before starting RDS binlog parsing."],"tags":["rds","binlog","position","data-corruption","canal-parse"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}