vitessio/vitess · error

internal value %v get MySQL value length error: %v

Error message

internal value %v get MySQL value length error: %v

What it means

writeBinaryRow computes the encoded length of each row value with val2MySQLLen before building the binary protocol packet; if a value's type cannot be sized, the packet write aborts with this wrapped error. It indicates an internal value the MySQL wire encoder does not know how to serialize.

Source

Thrown at go/mysql/query.go:1192

		if c.Capabilities&CapabilityClientDeprecateEOF == 0 {
			// With CapabilityClientDeprecateEOF, we do not send this EOF.
			if err := c.writeEOFPacket(c.StatusFlags, 0); err != nil {
				return err
			}
		}
	}

	return nil
}

func (c *Conn) writeBinaryRow(fields []*querypb.Field, row []sqltypes.Value) error {
	length := 0
	nullBitMapLen := (len(fields) + 7 + 2) / 8
	for _, val := range row {
		if !val.IsNull() {
			l, err := val2MySQLLen(val)
			if err != nil {
				return fmt.Errorf("internal value %v get MySQL value length error: %v", val, err)
			}
			length += l
		}
	}

	length += nullBitMapLen + 1

	data, pos := c.startEphemeralPacketWithHeader(length)

	pos = writeByte(data, pos, 0x00)

	for range nullBitMapLen {
		pos = writeByte(data, pos, 0x00)
	}

	for i, val := range row {
		if val.IsNull() {
			bytePos := (i+2)/8 + 1 + PacketHeaderSize

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the column type in the fields metadata and ensure it is a supported wire type
  2. Cast/convert the offending column to a supported type in the query (e.g. CAST(col AS CHAR))
  3. Report/investigate if an internal vitess Value type is reaching writeBinaryRow unencoded

Example fix

// before
SELECT weird_col FROM t
// after
SELECT CAST(weird_col AS CHAR) AS weird_col FROM t
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check supported types before executing the query
for _, f := range fields {
	switch f.Type {
	case query.Type_INT8, query.Type_UINT8, query.Type_INT16, query.Type_UINT16,
		query.Type_INT24, query.Type_UINT24, query.Type_INT32, query.Type_UINT32,
		query.Type_INT64, query.Type_UINT64, query.Type_FLOAT32, query.Type_FLOAT64,
		query.Type_VARCHAR, query.Type_VARBINARY, query.Type_DATETIME, query.Type_DATE,
		query.Type_TIME, query.Type_TIMESTAMP, query.Type_YEAR, query.Type_BIT,
		query.Type_ENUM, query.Type_SET, query.Type_NEWDECIMAL:
		// supported
	default:
		return fmt.Errorf("unsupported column type %v for binary protocol", f.Type)
	}
}

Try / catch

if err := conn.WriteBinaryRows(fields, rows); err != nil {
	if strings.Contains(err.Error(), "get MySQL value length error") {
		// fall back to text protocol or cast columns to supported types
	}
	return err
}

Prevention

When it happens

Trigger: A query result row contains a Value whose type has no binary-protocol length mapping (val2MySQLLen returns an error) while writing binary rows for a prepared-statement result.

Common situations: Vitess serving a result set containing an unsupported/internal column type over the MySQL protocol; mismatches between field type metadata and actual values after a version change or unsupported type passthrough.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/996d030a09278471. Report an issue: GitHub.