{"record":{"id":"c455358a3219eaed","repo":"alibaba/canal","slug":"error-binlog-file-header","errorCode":null,"errorMessage":"Error binlog file header: {}","messagePattern":"Error binlog file header: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/FileLogFetcher.java","lineNumber":84,"sourceCode":"     */\r\n    public void open(String filePath, final long filePosition) throws FileNotFoundException, IOException {\r\n        open(new File(filePath), filePosition);\r\n    }\r\n\r\n    /**\r\n     * Open binlog file in local disk to fetch.\r\n     */\r\n    public void open(File file, final long filePosition) throws FileNotFoundException, IOException {\r\n        fin = new FileInputStream(file);\r\n\r\n        ensureCapacity(BIN_LOG_HEADER_SIZE);\r\n        if (BIN_LOG_HEADER_SIZE != fin.read(buffer, 0, BIN_LOG_HEADER_SIZE)) {\r\n            throw new IOException(\"No binlog file header\");\r\n        }\r\n\r\n        if (buffer[0] != BINLOG_MAGIC[0] || buffer[1] != BINLOG_MAGIC[1] || buffer[2] != BINLOG_MAGIC[2]\r\n            || buffer[3] != BINLOG_MAGIC[3]) {\r\n            throw new IOException(\"Error binlog file header: \"\r\n                                  + Arrays.toString(Arrays.copyOf(buffer, BIN_LOG_HEADER_SIZE)));\r\n        }\r\n\r\n        limit = 0;\r\n        origin = 0;\r\n        position = 0;\r\n\r\n        if (filePosition > BIN_LOG_HEADER_SIZE) {\r\n            final int maxFormatDescriptionEventLen = FormatDescriptionLogEvent.LOG_EVENT_MINIMAL_HEADER_LEN\r\n                                                     + FormatDescriptionLogEvent.ST_COMMON_HEADER_LEN_OFFSET\r\n                                                     + LogEvent.ENUM_END_EVENT + LogEvent.BINLOG_CHECKSUM_ALG_DESC_LEN\r\n                                                     + LogEvent.CHECKSUM_CRC32_SIGNATURE_LEN;\r\n\r\n            ensureCapacity(maxFormatDescriptionEventLen);\r\n            limit = fin.read(buffer, 0, maxFormatDescriptionEventLen);\r\n            limit = (int) getUint32(LogEvent.EVENT_LEN_OFFSET);\r\n            fin.getChannel().position(filePosition);\r\n        }\r","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/FileLogFetcher.java#L66-L102","documentation":"Thrown by FileLogFetcher.open() after reading exactly 4 header bytes that do not equal BINLOG_MAGIC ({0xfe, 'b','i','n'}). The file is long enough to have a header, but the magic bytes are wrong, so it is not a MySQL binlog file.","triggerScenarios":"FileLogFetcher reads 4 bytes into buffer and compares against BINLOG_MAGIC; the first four bytes differ (e.g. a gzip/relay-log.index/SQL text file), so it raises IOException with the offending bytes printed.","commonSituations":"Passing a compressed binlog (.gz), a relay-log index file, a plain SQL dump, a binary from a different engine, or a file with a byte-order mark prepended; reading the wrong file in a directory of similarly named files.","solutions":["Inspect the printed byte array in the message; {-2,98,105,110} would be correct magic, so any deviation confirms wrong content.","Ensure the path is the raw mysqld binlog (typically mysql-bin.NNNNNN), not a .gz/.zip/.index/.sql sibling.","Decompress first if the binlog was archived as gzip.","Re-fetch the binlog from the master if the on-disk copy is the wrong file."],"exampleFix":"// before\nfetcher.open(new File(path), pos); // first 4 bytes != {0xfe,'b','i','n'}\n\n// after - decompress archived binlogs before opening\nFile target = path.endsWith(\".gz\") ? gunzipTo(path) : new File(path);\nfetcher.open(target, pos);","handlingStrategy":"validation","validationCode":"// Verify the binlog magic before handing the file to the fetcher\ntry (RandomAccessFile raf = new RandomAccessFile(file, \"r\")) {\n    byte[] m = new byte[4];\n    raf.readFully(m);\n    if (m[0] != -2 || m[1] != 'b' || m[2] != 'i' || m[3] != 'n')\n        throw new IOException(\"not a binlog (bad magic): \" + file);\n}","typeGuard":null,"tryCatchPattern":"try { fetcher.open(file, pos); }\ncatch (IOException e) {\n    if (e.getMessage().startsWith(\"Error binlog file header\"))\n        throw new IOException(\"wrong file type - decompress if gz / pick the raw mysql-bin.NNNNNN\", e);\n    throw e;\n}","preventionTips":["Open raw mysqld binlogs (mysql-bin.NNNNNN), not .gz/.index/.sql siblings.","Decompress archived binlogs first.","Cross-check magic bytes {0xfe,'b','i','n'} before opening."],"tags":["binlog","file","filelogfetcher","magic-bytes","validation"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}