{"record":{"id":"80f597c72127fe6f","repo":"apache/seatunnel","slug":"invalid-lsn-format-s-expected-format-00000027","errorCode":null,"errorMessage":"Invalid LSN format: %s. Expected format: 00000027:00000a80:0003","messagePattern":"Invalid LSN format: (.+?)\\. Expected format: 00000027:00000a80:0003","errorType":"exception","errorClass":"SeaTunnelException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-sqlserver/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/sqlserver/utils/SqlServerUtils.java","lineNumber":356,"sourceCode":"                            \"Failed to convert timestamp %d (%s) to LSN: %s\",\n                            timestampMs, new Timestamp(timestampMs), e.getMessage()),\n                    e);\n        }\n    }\n\n    /**\n     * Convert LSN string to LsnOffset.\n     *\n     * @param lsnString LSN string in format \"00000027:00000a80:0003\"\n     * @return LsnOffset\n     */\n    public static LsnOffset lsnStringToOffset(String lsnString) {\n        try {\n            // Validate LSN format\n            Lsn.valueOf(lsnString);\n            return LsnOffset.valueOf(lsnString);\n        } catch (Exception e) {\n            throw new SeaTunnelException(\n                    String.format(\n                            \"Invalid LSN format: %s. Expected format: 00000027:00000a80:0003\",\n                            lsnString),\n                    e);\n        }\n    }\n\n    /** Get split scan query for the given table. */\n    public static String buildSplitScanQuery(\n            TableId tableId, SeaTunnelRowType rowType, boolean isFirstSplit, boolean isLastSplit) {\n        return buildSplitQuery(tableId, rowType, isFirstSplit, isLastSplit, -1, true);\n    }\n\n    /** Get table split data PreparedStatement. */\n    public static PreparedStatement readTableSplitDataStatement(\n            JdbcConnection jdbc,\n            String sql,\n            boolean isFirstSplit,","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-sqlserver/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/sqlserver/utils/SqlServerUtils.java#L338-L374","documentation":"lsnStringToOffset validates the supplied LSN string via Lsn.valueOf before creating an LsnOffset. If parsing fails (malformed string), it throws SeaTunnelException explaining the expected three-part hexadecimal format like 00000027:00000a80:0003.","triggerScenarios":"Calling lsnStringToOffset with a string that is not a valid three-segment hex LSN — wrong separators, wrong segment count, non-hex characters, empty string, or a decimal value.","commonSituations":"User copies an LSN without trailing segment (from backup logs), pastes a value with quotes/spaces, or provides an LSN from a different system (MySQL binlog pos, Oracle SCN).","solutions":["Use the exact three-part hex format VNNNNNNN:OOOOOOOO:PPPP, e.g. 00000027:00000a80:0003","Trim whitespace/quotes from the value before passing it","Take the LSN string directly from SQL Server output (e.g. SELECT sys.fn_cdc_get_max_lsn()) rather than hand-writing it","If you only have a timestamp, use timestampToLsn instead of constructing an LSN manually"],"exampleFix":"// before\nSqlServerUtils.lsnStringToOffset(\"0000002700000a800003\"); // missing separators\n// after\nSqlServerUtils.lsnStringToOffset(\"00000027:00000a80:0003\");","handlingStrategy":"validation","validationCode":"public static boolean isValidLsn(String s) {\n    return s != null && s.trim().matches(\"[0-9a-fA-F]{8}:[0-9a-fA-F]{8}:[0-9a-fA-F]{4}\");\n}\nif (!isValidLsn(lsnString)) throw new IllegalArgumentException(\"Bad LSN: \" + lsnString);","typeGuard":"static boolean isLsnLike(String s) {\n    return s != null && s.matches(\"\\\\p{XDigit}{8}:\\\\p{XDigit}{8}:\\\\p{XDigit}{4}\");\n}","tryCatchPattern":"try {\n    LsnOffset off = SqlServerUtils.lsnStringToOffset(lsnString.trim());\n} catch (SeaTunnelException e) {\n    // surface the exact offending string to the user\n}","preventionTips":["Copy LSNs verbatim from SQL Server functions like sys.fn_cdc_get_max_lsn()","Always trim quotes/whitespace before parsing","Never substitute MySQL binlog positions or SCNs for SQL Server LSNs"],"tags":["sqlserver","cdc","lsn","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}