apache/shardingsphere · error · UnsupportedSQLOperationException

MySQL JSON type meta in binlog should be range 1 to 4, but a

Error message

MySQL JSON type meta in binlog should be range 1 to 4, but actual value is: %s

What it means

Thrown while decoding a MySQL JSON column value from a binlog row event: the column metadata must be 1–4, selecting the width of the JSON payload length prefix (read as 1/2/3/4 bytes little-endian). Any other meta value throws UnsupportedSQLOperationException because the payload length cannot be located reliably.

Source

Thrown at database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/string/MySQLJsonBinlogProtocolValue.java:62

        try {
            return MySQLJsonValueDecoder.decode(newlyByteBuf);
        } finally {
            newlyByteBuf.release();
        }
    }
    
    private int readLengthFromMeta(final int columnMeta, final MySQLPacketPayload payload) {
        switch (columnMeta) {
            case 1:
                return payload.getByteBuf().readUnsignedByte();
            case 2:
                return payload.getByteBuf().readUnsignedShortLE();
            case 3:
                return payload.getByteBuf().readUnsignedMediumLE();
            case 4:
                return payload.readInt4();
            default:
                throw new UnsupportedSQLOperationException(String.format("MySQL JSON type meta in binlog should be range 1 to 4, but actual value is: %s", columnMeta));
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Verify the source server is MySQL (not MariaDB) at a supported version — MariaDB stores JSON differently and trips this check
  2. Validate with mysqlbinlog that the JSON column's meta byte in the TABLE_MAP event is 1–4
  3. Resync the binlog client from the current master status after schema changes to rebuild table metadata
  4. If a legitimate new encoding exists, add the case to readLengthFromMeta() and contribute upstream
Defensive patterns

Strategy: validation

Validate before calling

int meta = columnDefinition.getColumnMeta();
if (columnDefinition.getType() == MYSQL_TYPE_JSON && (meta < 1 || meta > 4)) {
    // likely MariaDB 'json' (LONGTEXT alias) or a stale table map: handle as text instead of decoding as MySQL JSON
    decodeAsLongText(columnDefinition, payload);
    return;
}

Try / catch

try {
    value = jsonValue.read(meta, payload);
} catch (UnsupportedSQLOperationException ex) {
    // record position, classify server (MySQL vs MariaDB), then resync or fall back to text decoding
    handleUnsupportedJsonMeta(eventHeader, meta, ex);
}

Prevention

When it happens

Trigger: Calling readLengthFromMeta() with columnMeta outside 1–4 when parsing a row event's JSON column in MySQLJsonBinlogProtocolValue.

Common situations: Consuming binlogs from MySQL forks (MariaDB's JSON is really a LONGTEXT alias with different meta) or versions whose JSON binlog encoding differs; event reader desynchronized after a schema change.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/bdbb2506656d9a39. Report an issue: GitHub.