alibaba/canal · critical · PositionNotFoundException
position timestamp is empty!
Error message
position timestamp is empty!
What it means
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.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/rds/RdsLocalBinlogEventParser.java:61
public void start() throws CanalParseException {
try {
Assert.notNull(accesskey);
Assert.notNull(secretkey);
Assert.notNull(instanceId);
Assert.notNull(url);
Assert.notNull(directory);
if (endTime == null) {
endTime = System.currentTimeMillis();
}
EntryPosition entryPosition = findStartPosition(null);
if (entryPosition == null) {
throw new PositionNotFoundException("position not found!");
}
Long startTimeInMill = entryPosition.getTimestamp();
if (startTimeInMill == null || startTimeInMill <= 0) {
throw new PositionNotFoundException("position timestamp is empty!");
}
startTime = startTimeInMill;
List<BinlogFile> binlogFiles = RdsBinlogOpenApi.listBinlogFiles(url,
accesskey,
secretkey,
instanceId,
new Date(startTime),
new Date(endTime));
if (binlogFiles.isEmpty()) {
throw new CanalParseException("start timestamp : " + startTimeInMill + " binlog files is empty");
}
binlogDownloadQueue = new BinlogDownloadQueue(binlogFiles, batchFileSize, directory);
binlogDownloadQueue.silenceDownload();
needWait = true;
// try to download one file,use to test server id
binlogDownloadQueue.tryOne();View on GitHub (pinned to 87be50e876)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Before starting, validate the position has a timestamp
EntryPosition pos = logPositionManager.getLatestIndexBy(destination);
if (pos != null && (pos.getTimestamp() == null || pos.getTimestamp() <= 0)) {
pos.setTimestamp(System.currentTimeMillis() - 86400000L); // set to yesterday
logPositionManager.persistLogPosition(destination, buildLogPosition(pos));
} Try / catch
try {
parser.start();
} catch (PositionNotFoundException e) {
if (e.getMessage().contains("timestamp is empty")) {
// patch the position with a valid timestamp and retry
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- position not found!
- [fixed timestamp] can't found begin/commit position before w
- preTransactionStartPosition greater than startPosition from
- start timestamp : {} binlog files is empty
- can't find start position for {}
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/52dfaaabaed8642f.
Report an issue: GitHub.