apache/seatunnel · error · SeaTunnelException
Invalid LSN format: %s. Expected format: 00000027:00000a80:0
Error message
Invalid LSN format: %s. Expected format: 00000027:00000a80:0003
What it means
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.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-sqlserver/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/sqlserver/utils/SqlServerUtils.java:356
"Failed to convert timestamp %d (%s) to LSN: %s",
timestampMs, new Timestamp(timestampMs), e.getMessage()),
e);
}
}
/**
* Convert LSN string to LsnOffset.
*
* @param lsnString LSN string in format "00000027:00000a80:0003"
* @return LsnOffset
*/
public static LsnOffset lsnStringToOffset(String lsnString) {
try {
// Validate LSN format
Lsn.valueOf(lsnString);
return LsnOffset.valueOf(lsnString);
} catch (Exception e) {
throw new SeaTunnelException(
String.format(
"Invalid LSN format: %s. Expected format: 00000027:00000a80:0003",
lsnString),
e);
}
}
/** Get split scan query for the given table. */
public static String buildSplitScanQuery(
TableId tableId, SeaTunnelRowType rowType, boolean isFirstSplit, boolean isLastSplit) {
return buildSplitQuery(tableId, rowType, isFirstSplit, isLastSplit, -1, true);
}
/** Get table split data PreparedStatement. */
public static PreparedStatement readTableSplitDataStatement(
JdbcConnection jdbc,
String sql,
boolean isFirstSplit,View on GitHub (pinned to cf67b549a7)
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
Example fix
// before
SqlServerUtils.lsnStringToOffset("0000002700000a800003"); // missing separators
// after
SqlServerUtils.lsnStringToOffset("00000027:00000a80:0003"); Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidLsn(String s) {
return s != null && s.trim().matches("[0-9a-fA-F]{8}:[0-9a-fA-F]{8}:[0-9a-fA-F]{4}");
}
if (!isValidLsn(lsnString)) throw new IllegalArgumentException("Bad LSN: " + lsnString); Type guard
static boolean isLsnLike(String s) {
return s != null && s.matches("\\p{XDigit}{8}:\\p{XDigit}{8}:\\p{XDigit}{4}");
} Try / catch
try {
LsnOffset off = SqlServerUtils.lsnStringToOffset(lsnString.trim());
} catch (SeaTunnelException e) {
// surface the exact offending string to the user
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- No LSN found for timestamp %d (%s)
- LSN is null for timestamp %d (%s). This may indicate that CD
- Failed to convert timestamp %d (%s) to LSN: %s
- Read the binlog offset error
- not supported create new Offset by filename and position.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/80f597c72127fe6f.
Report an issue: GitHub.