{"record":{"id":"403e4cb178c81eae","repo":"alibaba/canal","slug":"unexcepted-limit","errorCode":null,"errorMessage":"Unexcepted limit: {}","messagePattern":"Unexcepted limit: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/FileLogFetcher.java","lineNumber":158,"sourceCode":"                    return true;\r\n                } else {\r\n                    ensureCapacity((int) eventLen);\r\n                }\r\n            }\r\n\r\n            System.arraycopy(buffer, origin, buffer, 0, limit);\r\n            position -= origin;\r\n            origin = 0;\r\n            final int len = fin.read(buffer, limit, buffer.length - limit);\r\n            if (len >= 0) {\r\n                limit += len;\r\n\r\n                /* More binlog to fetch */\r\n                return true;\r\n            }\r\n        } else {\r\n            /* Should not happen. */\r\n            throw new IllegalArgumentException(\"Unexcepted limit: \" + limit);\r\n        }\r\n\r\n        /* Reach binlog file end */\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * {@inheritDoc}\r\n     * \r\n     * @see com.taobao.tddl.dbsync.binlog.LogFetcher#close()\r\n     */\r\n    public void close() throws IOException {\r\n        if (fin != null) {\r\n            fin.close();\r\n        }\r\n\r\n        fin = null;\r\n    }\r","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/FileLogFetcher.java#L140-L176","documentation":"Thrown by FileLogFetcher.fetch() in the else branch when 'limit' takes an unexpected value that violates the method's internal buffer-state invariant (the code comments it 'Should not happen'). It is a defensive guard indicating the fetcher's buffer positions got into an inconsistent state, almost always a consequence of upstream corruption rather than normal operation.","triggerScenarios":"fetch() computes buffer state and reaches the else branch whose precondition on 'limit' is not met - i.e. limit is negative or larger than buffer capacity after the compact/read logic, which should be impossible given the preceding arithmetic.","commonSituations":"A corrupted/truncated binlog file feeding the reader inconsistent event lengths; a race where the same FileLogFetcher is used concurrently (not thread-safe); memory corruption or a bug in a downstream subclass overriding ensureCapacity/forward that breaks position accounting.","solutions":["Treat this as data corruption: re-verify the binlog file with mysqlbinlog on the source; if it fails there too, the file is damaged.","Ensure a single FileLogFetcher instance is not shared across threads (it is not thread-safe).","Restart the fetch from an earlier known-good position/file rather than continuing past the corrupt region.","If reproducible on a known-good file, check for a subclass overriding LogBuffer/LogFetcher methods that mismanage position/limit."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Guard the fetcher's buffer invariant defensively in a wrapper\npublic boolean safeFetch(FileLogFetcher f) throws IOException {\n    try { return f.fetch(); }\n    catch (IllegalArgumentException e) {\n        if (e.getMessage().startsWith(\"Unexcepted limit\"))\n            throw new IOException(\"binlog corruption / unsafe concurrent use\", e);\n        throw e;\n    }\n}","typeGuard":null,"tryCatchPattern":"try { while (fetcher.fetch()) { /* decode */ } }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unexcepted limit\"))\n        throw new IOException(\"file/log fetcher state corrupted - re-open from good position\", e);\n    throw e;\n}","preventionTips":["Never share one FileLogFetcher across threads.","Validate the binlog file with mysqlbinlog on the source before replaying.","Restart from a known-good position on a state-invariant error."],"tags":["binlog","filelogfetcher","invariant","corruption","thread-safety"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}