vitessio/vitess · error
expecting field event first, got: %v
Error message
expecting field event first, got: %v
What it means
In vcopier_atomic (atomic copy mode), when the copy queue for a table is not open the code expects the response to carry field metadata (resp.Fields). If a rows response arrives with no fields, the copier cannot decode the rows and returns 'expecting field event first'. It is the atomic-mode counterpart of the vcopier.go:494 error.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go:164
copyWorkQueue.close()
}
copyWorkQueue = vc.newCopyWorkQueue(parallelism, copyWorkerFactory)
if state.currentTableName != "" {
log.Info(fmt.Sprintf("copy of table %s is done at lastpk %+v", state.currentTableName, lastpkbv))
if err := vc.runPostCopyActionsAndDeleteCopyState(ctx, stopCtx, state.currentTableName); err != nil {
return err
}
} else {
log.Info("starting copy phase with table " + tableName)
}
state.currentTableName = tableName
}
// A new copy queue is created for each table. The queue is closed when the table is done.
if !copyWorkQueue.isOpen {
if len(resp.Fields) == 0 {
return fmt.Errorf("expecting field event first, got: %v", resp)
}
lastpk = nil
// pkfields are only used for logging, so that we can monitor progress.
pkfields = make([]*querypb.Field, 0, len(resp.Pkfields))
for _, f := range resp.Pkfields {
pkfields = append(pkfields, f.CloneVT())
}
fieldEvent := &binlogdatapb.FieldEvent{
TableName: tableName,
}
for _, f := range resp.Fields {
fieldEvent.Fields = append(fieldEvent.Fields, f.CloneVT())
}
tablePlan, err := state.plan.buildExecutionPlan(fieldEvent)
if err != nil {
return errView on GitHub (pinned to 01a25a7d17)
Solutions
- Restart the VReplication workflow so the copy phase re-receives field events from the start
- Check earlier logs for failures fetching field info for the table
- Verify the source table schema is readable and unchanged during copy
- Retry the copy phase; if reproducible, report with the GTID/binlog position
Defensive patterns
Strategy: retry
Try / catch
if err := vc.copyNext(ctx); err != nil {
if strings.Contains(err.Error(), "expecting field event first") {
// restart the atomic copy phase so field events are re-delivered
}
return err
} Prevention
- Avoid controller restarts mid-atomic-copy; restart the full phase instead
- Keep source schema stable during copy
- Monitor logs for field-info fetch failures before row streaming begins
When it happens
Trigger: copyNext (atomic path) receives a rows response for a table whose queue is closed/just-opened and resp.Fields is empty — the field event for the table was never delivered or was lost before rows.
Common situations: Atomic copy resuming after controller restart with lost cached schema; source sending rows for a table before its field event; binlog stream misordering or schema-cache eviction.
Related errors
- expecting field event first, got: %v
- empty gtid passed to setPosition
- partial row image encountered: ensure binlog_row_image is se
- value out of range
- GetPreviousGTIDs: previous GTIDs not found
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c9025783314da456.
Report an issue: GitHub.