vitessio/vitess · error
err.Error() (ReadTwopcInflight failure)
Error message
err.Error() (ReadTwopcInflight failure)
What it means
This is the HTTP 500 returned by the /twopcz debug UI handler when txe.ReadTwopcInflight() fails to enumerate in-flight distributed transactions. ReadTwopcInflight queries the underlying transaction store (and MySQL) for unresolved prepared/distributed transactions; a failure here means the dtid transaction metadata could not be read (storage/backend error). The raw err.Error() text is written as the HTTP 500 body.
Source
Thrown at go/vt/vttablet/tabletserver/twopcz.go:160
switch action {
case "Discard", "Rollback":
err = txe.RollbackPrepared(dtid, 0)
case "Commit":
err = txe.CommitPrepared(dtid)
case "Conclude":
err = txe.ConcludeTransaction(dtid)
}
var msg string
if action != "" {
if err != nil {
msg = fmt.Sprintf("%s(%s): %v", r.FormValue("Action"), dtid, err)
} else {
msg = fmt.Sprintf("%s(%s): completed.", r.FormValue("Action"), dtid)
}
}
distributed, prepared, failed, err := txe.ReadTwopcInflight()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
format := r.FormValue("format")
if format == "json" {
w.Header().Set("Content-Type", "application/json")
js, err := json.Marshal(struct {
Distributed []*tx.DistributedTx
Prepared, Failed []*tx.PreparedTx
}{
Distributed: distributed,
Prepared: prepared,
Failed: failed,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")View on GitHub (pinned to 01a25a7d17)
Solutions
- Read the error body — it is the raw ReadTwopcInflight error — and fix the underlying storage/MySQL issue it names.
- Check vttablet logs for the full error with context around the /twopcz request.
- Verify the MySQL backend is healthy and the transaction metadata table (dtid store) exists and is readable; run a manual SELECT against it to confirm.
- Retry after restoring MySQL connectivity; if metadata is corrupt, follow the 2PC recovery runbook (ResolveTransactions/ConcludeTransaction) carefully to avoid data loss.
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm MySQL backend reachable before calling /twopcz
if err := mysqlPing(ctx, tabletDSN); err != nil {
return fmt.Errorf("backend down, /twopcz will fail: %w", err)
} Try / catch
resp, err := http.Get(tabletURL + "/twopcz")
if err != nil {
return err
}
if resp.StatusCode == http.StatusInternalServerError {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("ReadTwopcInflight failed: %s", body)
} Prevention
- Monitor the dtid/transaction metadata storage for corruption or unavailability.
- Resolve in-flight distributed transactions promptly instead of accumulating unbounded 2PC state.
- Only operate /twopcz during controlled recovery windows with MySQL confirmed healthy.
- Back up and test recovery of the transaction metadata store.
When it happens
Trigger: An HTTP GET to the vttablet /twopcz endpoint (acl DEBUGGING required) where txe.ReadTwopcInflight() returns an error — e.g. the dtid table in the transaction metadata storage is unreadable/corrupt, the backing MySQL query fails, or the transaction store is not available.
Common situations: Investigating unresolved distributed transactions after a crash and the transaction metadata storage is damaged; probing /twopcz on a tablet whose MySQL backend is down; scripting /twopcz during a failover when the transaction store is temporarily inaccessible.
Related errors
- err.Error() (JSON marshal failure)
- BeforeSchema differs
- AfterSchema differs
- must be non-negative
- watch terminated with no error
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/13d3c21a6deace9b.
Report an issue: GitHub.