alibaba/canal · error · IOException

Error INT_RESULT length:

Error message

Error INT_RESULT length: 

What it means

Thrown while decoding a UserVarLogEvent whose value type is INT_RESULT. MySQL stores INT user variables as either 4-byte (32-bit) or 8-byte (64-bit) values. If the declared valueLen is neither 4 nor 8, the payload is structurally invalid and an IOException is thrown. This guards against truncation or corruption of the user-variable value section.

Source

Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/UserVarLogEvent.java:96

            charsetNumber = 63; /* binary */
            value = null;
        } else {
            type = buffer.getInt8(); // UV_VAL_IS_NULL
            charsetNumber = (int) buffer.getUint32(); // buf + UV_VAL_TYPE_SIZE
            final int valueLen = (int) buffer.getUint32(); // buf +
                                                           // UV_CHARSET_NUMBER_SIZE
            final int limit = buffer.limit(); /* for restore */
            buffer.limit(buffer.position() + valueLen);

            /* @see User_var_log_event::print */
            switch (type) {
                case REAL_RESULT:
                    value = Double.valueOf(buffer.getDouble64()); // float8get
                    break;
                case INT_RESULT:
                    if (valueLen == 8) value = Long.valueOf(buffer.getLong64()); // !uint8korr
                    else if (valueLen == 4) value = Long.valueOf(buffer.getUint32());
                    else throw new IOException("Error INT_RESULT length: " + valueLen);
                    break;
                case DECIMAL_RESULT:
                    final int precision = buffer.getInt8();
                    final int scale = buffer.getInt8();
                    value = buffer.getDecimal(precision, scale); // bin2decimal
                    break;
                case STRING_RESULT:
                    Charset charset = CharsetConversion.getNioCharset(charsetNumber);
                    value = buffer.getFixString(valueLen, charset);
                    break;
                case ROW_RESULT:
                    // this seems to be banned in MySQL altogether
                    throw new IOException("ROW_RESULT is unsupported");
                default:
                    value = null;
                    break;
            }
            buffer.limit(limit);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Inspect the binlog at the reported position with mysqlbinlog to confirm the UserVar event is intact.
  2. If the binlog is corrupt, reseed Canal from a valid position.
  3. Upgrade Canal to match the master version.
  4. Avoid relying on user-variable events if the replication target does not need them.
Defensive patterns

Strategy: try-catch

Validate before calling

boolean isValidIntResultLen(int valueLen) {
    return valueLen == 4 || valueLen == 8;
}

Try / catch

try {
    userVarEvent.parse();
} catch (IOException e) {
    if (e.getMessage().startsWith("Error INT_RESULT length")) {
        logger.warn("Corrupt INT user variable, skipping event");
        // skip / null the value
    } else throw e;
}

Prevention

When it happens

Trigger: A UserVarLogEvent with type INT_RESULT and a value length other than 4 or 8 bytes. Produced by binlog corruption, truncation, or a source that mis-encodes user-variable events.

Common situations: Replicating SET @var = <bigint> statements from a corrupted binlog; a partial binlog read; a MySQL fork with non-standard user-variable encoding.

Related errors


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