alibaba/canal · error · RuntimeException

parseUUIDSet failed due to wrong format: %s

Error message

parseUUIDSet failed due to wrong format: %s

What it means

Thrown by UUIDSet.parse(String) when the input string does not contain at least one ':' separating the UUID (SID) from its transaction-id intervals. The parser splits on ':' and requires a minimum of two segments: the UUID and at least one interval such as '1-3'. The canonical GTID-set format is '<UUID>:<interval>[:<interval>...]'. Without the delimiter, no UUID/interval split is possible and the whole value is treated as malformed.

Source

Thrown at driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/packets/UUIDSet.java:105

    /**
     * 解析如下格式字符串为UUIDSet: 726757ad-4455-11e8-ae04-0242ac110002:1 => UUIDSet{SID:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervals: [{start:1, stop:2}]}
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3 => UUIDSet{SID:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervals: [{start:1, stop:4}]}
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3:4 UUIDSet{SID:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervals: [{start:1, stop:5}]}
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3:7-9 UUIDSet{SID:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervals: [{start:1, stop:4},
     * {start:7, stop:10}]}
     *
     * @param str
     * @return
     */
    public static UUIDSet parse(String str) {
        String[] ss = str.split(":");

        if (ss.length < 2) {
            throw new RuntimeException(String.format("parseUUIDSet failed due to wrong format: %s", str));
        }

        List<Interval> intervals = new ArrayList<>();
        for (int i = 1; i < ss.length; i++) {
            intervals.add(parseInterval(ss[i]));
        }

        UUIDSet uuidSet = new UUIDSet();
        uuidSet.SID = UUID.fromString(ss[0]);
        uuidSet.intervals = combine(intervals);

        return uuidSet;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

View on GitHub (pinned to 87be50e876)

Solutions

  1. Ensure the input string matches '<UUID>:<interval>' e.g. '726757ad-4455-11e8-ae04-0242ac110002:1-3' before calling parse.
  2. Validate the string with a regex such as '^[0-9a-fA-F-]{36}:.+$' and reject/repair malformed input upstream.
  3. If you only have a UUID, append a default interval (e.g. ':1') or skip UUIDSet parsing entirely.
  4. Log the raw str value at the call site to find which producer emitted the bad GTID string.

Example fix

// before
UUIDSet set = UUIDSet.parse(gtidStr); // gtidStr = "726757ad-4455-11e8-ae04-0242ac110002"

// after
if (gtidStr == null || !gtidStr.contains(":")) {
    throw new IllegalArgumentException("Invalid GTID set, expected '<UUID>:<interval>': " + gtidStr);
}
UUIDSet set = UUIDSet.parse(gtidStr);
Defensive patterns

Strategy: validation

Validate before calling

public static boolean isValidGtidSet(String s) {
    return s != null && s.matches("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}:.+");
}
// before UUIDSet.parse(str): if (!isValidGtidSet(str)) throw new IllegalArgumentException(...);

Type guard

public static boolean isParsableGtidSet(String s) {
    if (s == null) return false;
    String[] parts = s.split(":");
    if (parts.length < 2) return false;
    try { java.util.UUID.fromString(parts[0]); return true; }
    catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
    UUIDSet set = UUIDSet.parse(str);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("parseUUIDSet failed")) {
        // log str, reject position, surface a clear config error
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling UUIDSet.parse(str) with a string that has no ':' (e.g. '726757ad-4455-11e8-ae04-0242ac110002'), an empty string, or a value whose first segment is a bare UUID with no interval suffix. Also triggered when downstream code feeds a GTID string that has been truncated or already had its interval portion stripped.

Common situations: Manually constructed GTID strings missing the interval part; copying only the UUID portion from 'show master status'; a custom binlog position parser that trims at the wrong delimiter; GTID values read from a config file where trailing intervals were lost; database upgraded to a GTID representation the older parser does not expect.

Related errors


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