alibaba/canal · error · RuntimeException

parseInterval failed due to wrong format: %s

Error message

parseInterval failed due to wrong format: %s

What it means

Thrown by UUIDSet.parseInterval(String) when an interval segment splits into more than two pieces on '-'. Valid intervals are either a single number '5' (open-ended, start..start+1) or a closed range '1-3'. More than one '-' (e.g. '1-3-5') or a leading/trailing '-' producing empty tokens falls into the default switch case. Note the format uses inclusive bounds in the string but a half-open [start, stop) internally.

Source

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

     *
     * @param str
     * @return
     */
    public static Interval parseInterval(String str) {
        String[] ss = str.split("-");

        Interval interval = new Interval();
        switch (ss.length) {
            case 1:
                interval.start = Long.parseLong(ss[0]);
                interval.stop = interval.start + 1;
                break;
            case 2:
                interval.start = Long.parseLong(ss[0]);
                interval.stop = Long.parseLong(ss[1]) + 1;
                break;
            default:
                throw new RuntimeException(String.format("parseInterval failed due to wrong format: %s", str));
        }

        return interval;
    }

    /**
     * 把{start,stop}连续的合并掉: [{start:1, stop:4},{start:4, stop:5}] => [{start:1,
     * stop:5}]
     *
     * @param intervals
     * @return
     */
    public static List<Interval> combine(List<Interval> intervals) {
        List<Interval> combined = new ArrayList<>();
        Collections.sort(intervals);
        int len = intervals.size();
        for (int i = 0; i < len; i++) {
            combined.add(intervals.get(i));

View on GitHub (pinned to 87be50e876)

Solutions

  1. Verify each interval token is either 'N' or 'N-M' (two non-negative integers, one optional dash) before parsing.
  2. Sanitize the token: strip non-numeric characters except a single internal dash.
  3. Log the offending token from UUIDSet.parse to localize which interval failed.
  4. If you control the producer, emit canonical GTID ranges only.

Example fix

// before
UUIDSet.parse("726757ad-4455-11e8-ae04-0242ac110002:1-3-5");

// after
private static boolean validInterval(String tok) {
    return tok.matches("\\d+(-\\d+)?");
}
String[] parts = gtidStr.split(":");
for (int i = 1; i < parts.length; i++) {
    if (!validInterval(parts[i])) throw new IllegalArgumentException("Bad interval: " + parts[i]);
}
Defensive patterns

Strategy: validation

Validate before calling

private static final java.util.regex.Pattern INTERVAL = java.util.regex.Pattern.compile("^\\d+(-\\d+)?$");
public static boolean isValidInterval(String tok) { return tok != null && INTERVAL.matcher(tok).matches(); }

Type guard

public static boolean isParsableInterval(String s) {
    if (s == null) return false;
    String[] ss = s.split("-");
    if (ss.length < 1 || ss.length > 2) return false;
    try { for (String t : ss) Long.parseLong(t); return true; }
    catch (NumberFormatException e) { return false; }
}

Try / catch

try {
    UUIDSet.Interval iv = UUIDSet.parseInterval(tok);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("parseInterval failed")) { /* reject token */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling parseInterval on a substring containing '1-3-5', a negative-looking value, or a value with stray dashes. Indirectly triggered from UUIDSet.parse when any interval token after the UUID is malformed, e.g. 'UUID:1-3:bad-interval'.

Common situations: Hand-edited GTID intervals; a monitoring/serialization tool that joined ranges with extra dashes; version where MySQL emits an interval representation the parser does not yet handle; copy-paste of a hyphenated comment into the GTID field.

Related errors


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