vitessio/vitess · error

Not implemented, post_header_length==6

Error message

Not implemented, post_header_length==6

What it means

newRowsEvent (behind NewWriteRowsEvent, NewUpdateRowsEvent, NewDeleteRowsEvent) only supports row-events with a post-header length of 8 (V2-style). If the binlog format's header size for the row event type is 6 (the old V1 layout), the constructor panics because the 6-byte layout is not implemented.

Source

Thrown at go/mysql/binlog_event_make.go:423

}

// NewUpdateRowsEvent returns an UpdateRows event. Uses v2.
func NewUpdateRowsEvent(f BinlogFormat, s *FakeBinlogStream, tableID uint64, rows Rows) BinlogEvent {
	return newRowsEvent(f, s, eUpdateRowsEventV2, tableID, rows)
}

// NewDeleteRowsEvent returns an DeleteRows event. Uses v2.
func NewDeleteRowsEvent(f BinlogFormat, s *FakeBinlogStream, tableID uint64, rows Rows) BinlogEvent {
	return newRowsEvent(f, s, eDeleteRowsEventV2, tableID, rows)
}

// newRowsEvent can create an event of type:
// eWriteRowsEventV1, eWriteRowsEventV2,
// eUpdateRowsEventV1, eUpdateRowsEventV2,
// eDeleteRowsEventV1, eDeleteRowsEventV2.
func newRowsEvent(f BinlogFormat, s *FakeBinlogStream, typ byte, tableID uint64, rows Rows) BinlogEvent {
	if f.HeaderSize(typ) == 6 {
		panic("Not implemented, post_header_length==6")
	}

	hasIdentify := typ == eUpdateRowsEventV1 || typ == eUpdateRowsEventV2 ||
		typ == eDeleteRowsEventV1 || typ == eDeleteRowsEventV2
	hasData := typ == eWriteRowsEventV1 || typ == eWriteRowsEventV2 ||
		typ == eUpdateRowsEventV1 || typ == eUpdateRowsEventV2

	rowLen := rows.DataColumns.Count()
	if hasIdentify {
		rowLen = rows.IdentifyColumns.Count()
	}

	length := 6 + // table id
		2 + // flags
		2 + // extra data length, no extra data.
		lenEncIntSize(uint64(rowLen)) + // num columns
		len(rows.IdentifyColumns.data) + // only > 0 for Update & Delete
		len(rows.DataColumns.data) // only > 0 for Write & Update

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Use a BinlogFormat with an 8-byte post-header length for the row event type (V2 events, MySQL 5.6+).
  2. Parse the format description from the actual binlog rather than fabricating header sizes.
  3. If V1 row events must be produced/parsed, implement a separate code path.

Example fix

// before
f.HeaderSize[eWriteRowsEventV2] = 6
ev := mysql.NewWriteRowsEvent(f, s, id, rows) // panics
// after
f.HeaderSize[eWriteRowsEventV2] = 8
ev := mysql.NewWriteRowsEvent(f, s, id, rows)
Defensive patterns

Strategy: validation

Validate before calling

if f.HeaderSize(mysql.EWriteRowsEventV2) == 6 {
    return errors.New("row-event post_header_length 6 (V1) is unsupported")
}
ev := mysql.NewWriteRowsEvent(f, s, tableID, rows)

Try / catch

func safeRowsEvent(make func() mysql.BinlogEvent) (ev mysql.BinlogEvent, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("rows event: %v", r)
        }
    }()
    return make(), nil
}

Prevention

When it happens

Trigger: Calling NewWriteRowsEvent / NewUpdateRowsEvent / NewDeleteRowsEvent with a BinlogFormat whose HeaderSize(typ) == 6 for the requested row-event type.

Common situations: Testing against synthetic formats modeled on very old MySQL 5.1 row events (V1); copying header sizes from the table-map event (6 in some flavors) into row-event header sizes; tools replaying legacy binlog formats.

Related errors


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