vitessio/vitess · error
internal error: vplayer is in a transaction on event: %v
Error message
internal error: vplayer is in a transaction on event: %v
What it means
A defensive, marked-unreachable error: when an OTHER-type vstream event arrives, vplayer requires that it is not inside a database transaction, because OTHER events only update the stored position and must not commit mid-transaction state. If dbClient.InTransaction is true at that point, internal transaction bookkeeping is broken, so it logs and returns this internal error.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/vplayer.go:790
}
if err := vp.applyStmtEvent(ctx, event); err != nil {
return err
}
}
case binlogdatapb.VEventType_ROW:
// This player is configured for row based replication
if err := vp.vr.dbClient.Begin(); err != nil {
return err
}
if err := vp.applyRowEvent(ctx, event.RowEvent); err != nil {
log.Info("Error applying row event: " + err.Error())
return err
}
case binlogdatapb.VEventType_OTHER:
if vp.vr.dbClient.InTransaction {
// Unreachable
log.Error(fmt.Sprintf("internal error: vplayer is in a transaction on event: %v", event))
return fmt.Errorf("internal error: vplayer is in a transaction on event: %v", event)
}
// Just update the position.
posReached, err := vp.updatePos(ctx, event.Timestamp)
if err != nil {
return err
}
if posReached {
return io.EOF
}
case binlogdatapb.VEventType_DDL:
if vp.vr.dbClient.InTransaction {
// Unreachable
log.Error(fmt.Sprintf("internal error: vplayer is in a transaction on event: %v", event))
return fmt.Errorf("internal error: vplayer is in a transaction on event: %v", event)
}
vp.vr.stats.DDLEventActions.Add(vp.vr.source.OnDdl.String(), 1) // Record the DDL handling
switch vp.vr.source.OnDdl {
case binlogdatapb.OnDDLAction_IGNORE:View on GitHub (pinned to 01a25a7d17)
Solutions
- Treat as a Vitess bug: file an issue with the tablet logs, workflow name, and the event details from the 'internal error' log line
- Check preceding log lines for a failed commit/rollback that left the transaction open; identify the original error
- Restart the vreplication workflow (or the tablet) to reset transaction state and let it re-apply from the last saved position
- Verify you are on a supported Vitess release; upgrade if a fix for the leaked transaction exists
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "internal error: vplayer is in a transaction") {
// This is an invariant violation: capture logs, restart the workflow,
// and file a Vitess issue with the event and preceding errors
} Prevention
- Don't patch the vplayer event loop without preserving commit-before-non-row-event ordering
- Ensure no error path leaves dbClient with an open transaction (always commit/rollback on error)
- Run supported Vitess releases; this error signals an upstream bug
- Keep tablet logs around to diagnose the original leaked-transaction cause
When it happens
Trigger: applyEvent receives a VEventType_OTHER event while vp.vr.dbClient.InTransaction is true — meaning a previous row-event transaction was left open instead of being committed/rolled back before the non-row event.
Common situations: Upstream bug where transaction commit was skipped on an error path; partial event application interrupted without rollback; custom patched builds altering the event loop; true internal invariant violation after an earlier swallowed error.
Related errors
- unexpected: there are no tables to copy
- progress stalled; vplayer was unable to replicate the transa
- vstream ended
- panic in %s: %v
- value out of range
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c04826545730eb98.
Report an issue: GitHub.