vitessio/vitess · error
failed to marshal pk fields and value into query result: %s
Error message
failed to marshal pk fields and value into query result: %s
What it means
This error is thrown during VReplication copy when marshalling the primary-key fields and last copied row into a querypb.QueryResult (via prototext.Marshal) fails. The marshalled result is bound as the :lastpk bind variable in the next copy batch query, so a marshal failure means the copy-continuation state cannot be built. It is effectively an internal/serialization error, since querypb types normally marshal cleanly.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go:205
"insert into _vt.copy_state (lastpk, vrepl_id, table_name) values (%a, %s, %s)", ":lastpk",
strconv.Itoa(int(vc.vr.id)),
encodeString(tableName),
)
addLatestCopyState := buf.ParsedQuery()
copyWorkQueue.open(addLatestCopyState, pkfields, tablePlan)
}
// When rowstreamer has finished streaming all rows, we get a callback with empty rows.
if len(resp.Rows) == 0 {
return nil
}
// Get the last committed pk into a loggable form.
lastpkbuf, merr := prototext.Marshal(&querypb.QueryResult{
Fields: pkfields,
Rows: []*querypb.Row{lastpk},
})
if merr != nil {
return fmt.Errorf("failed to marshal pk fields and value into query result: %s", merr.Error())
}
lastpkbv = map[string]*querypb.BindVariable{
"lastpk": {
Type: sqltypes.VarBinary,
Value: lastpkbuf,
},
}
log.Info(fmt.Sprintf("copying table %s with lastpk %v", tableName, lastpkbv))
// Prepare a vcopierCopyTask for the current batch of work.
currCh := make(chan *vcopierCopyTaskResult, 1)
if parallelism > 1 {
resp = resp.CloneVT()
}
currT := newVCopierCopyTask(newVCopierCopyTaskArgs(resp.Rows, resp.Lastpk))
// Send result to the global resultCh and currCh. resultCh is used by
// the loop to return results to VStreamRows. currCh will be used toView on GitHub (pinned to 01a25a7d17)
Solutions
- Inspect the %s detail (the underlying merr) in the error message to identify which field/value failed to marshal
- Verify the source table's primary key columns exist and their types match what vreplication discovered (check SHOW CREATE TABLE on source vs the copied schema)
- Retry the workflow; if reproducible, collect the exact table/columns and file a Vitess issue with the marshal error text
- Check the Vitess version for known vcopier serialization bugs and upgrade to a patched release
Defensive patterns
Strategy: validation
Validate before calling
// Before starting/retrying a copy workflow, verify the source PK schema is discoverable
cols := vtctldClient.GetWorkflow(workflowName).CopyState[table]
if len(cols.PKColumns) == 0 {
return fmt.Errorf("table %s has no discoverable primary key; fix schema before copy", table)
} Try / catch
err := vtctldClient.WorkflowStart(...)
if err != nil && strings.Contains(err.Error(), "failed to marshal pk fields") {
// inspect merr detail, verify source schema, then retry
log.Error("copy marshal failure", slog.Any("error", err))
} Prevention
- Ensure every copied table has a well-defined primary key matching between source and target
- Keep source and target schemas in sync before starting MoveTables/VCopy
- Watch for prototext/querypb-related fixes in release notes and stay on a current patch release
When it happens
Trigger: prototext.Marshal fails on the constructed &querypb.QueryResult{Fields: pkfields, Rows: []*querypb.Row{lastpk}} in vcopier's copy loop — e.g. malformed or nil field/row contents fed into the query result used for the lastpk bind variable.
Common situations: Corrupted or empty source table schema/primary key info during MoveTables/VCopy; a source row whose field descriptors do not match the row data; bugs in custom or filtered copy flows supplying inconsistent pkfields.
Related errors
- unmarshal primary health state: %w
- marshal primary health state: %w
- value out of range
- both atomic copy and partial mode cannot be specified for th
- invalid workflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/2ca332272eb0de72.
Report an issue: GitHub.