alibaba/canal · critical · CanalParseException

Binlog index missing or unreadable; {}

Error message

Binlog index missing or unreadable;  {}

What it means

Thrown from the BinLogFileQueue constructor when the specified directory cannot be read (!directory.canRead()). BinLogFileQueue is used in local file-based binlog parsing mode — Canal reads binlog files from a local filesystem directory instead of connecting to a live MySQL server. If the directory doesn't exist or the JVM process lacks read permission, this exception fires at construction time.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/local/BinLogFileQueue.java:45

    private String              baseName       = "mysql-bin.";
    private List<File>          binlogs        = new ArrayList<>();
    private Pattern binLogPattern = Pattern.compile(baseName + "\\d+$");
    private File                directory;
    private ReentrantLock       lock           = new ReentrantLock();
    private Condition           nextCondition  = lock.newCondition();
    private Timer               timer          = new Timer(true);
    private long                reloadInterval = 10 * 1000L;           // 10秒
    private CanalParseException exception      = null;

    public BinLogFileQueue(String directory){
        this(new File(directory));
    }

    public BinLogFileQueue(File directory){
        this.directory = directory;

        if (!directory.canRead()) {
            throw new CanalParseException("Binlog index missing or unreadable;  " + directory.getAbsolutePath());
        }

        List<File> files = listBinlogFiles();
        for (File file : files) {
            offer(file);
        }

        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                try {
                    // File errorFile = new File(BinLogFileQueue.this.directory,
                    // errorFileName);
                    // if (errorFile.isFile() && errorFile.exists()) {
                    // String text = StringUtils.join(IOUtils.readLines(new
                    // FileInputStream(errorFile)), "\n");
                    // exception = new CanalParseException(text);
                    // }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Verify the directory exists: ls -la /path/to/binlogs and check the permissions.
  2. Ensure the JVM process owner has read+execute permission on the directory: chmod 755 /path/to/binlogs.
  3. Double-check the canal instance configuration for the correct directory path.
  4. If using a remote mount (NFS/S3FS), verify the mount is active and accessible.

Example fix

# before
canal.instance.binlog.directory=/var/lib/mysql-binlog

# after — correct path with verified permissions
canal.instance.binlog.directory=/data/canal/binlogs
# ensure: chown canal:canal /data/canal/binlogs && chmod 755 /data/canal/binlogs
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing BinLogFileQueue, validate the directory
File dir = new File(configuredDirectory);
if (!dir.exists()) {
    throw new IllegalArgumentException("Binlog directory does not exist: " + dir.getAbsolutePath());
}
if (!dir.isDirectory()) {
    throw new IllegalArgumentException("Path is not a directory: " + dir.getAbsolutePath());
}
if (!dir.canRead()) {
    throw new IllegalArgumentException("Cannot read directory (check permissions): " + dir.getAbsolutePath());
}

Try / catch

try {
    BinLogFileQueue queue = new BinLogFileQueue(directory);
} catch (CanalParseException e) {
    if (e.getMessage().contains("Binlog index missing or unreadable")) {
        // Guide the user: create the directory or fix permissions
        throw new ConfigurationException("Binlog directory inaccessible: " + directory
            + ". Verify path exists and JVM has read permission.", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: new BinLogFileQueue(directory) is called and directory.canRead() returns false. The directory path is wrong, the directory doesn't exist, or the OS file permissions deny read access to the JVM user. This is used by the local/binlog-file parsing mode, not the standard network-based mode.

Common situations: The canal.instance.statement directory path is misconfigured or has a typo. The binlog files were downloaded to a different directory. The JVM process runs as a different OS user than expected and lacks read permission on the directory. The mount point is not mounted (NFS/glusterFS failure). The directory was cleaned up by a cron job.

Related errors


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