{"record":{"id":"590eea176e9bd034","repo":"vitessio/vitess","slug":"invalid-connection-id-found-d-when-attempting-t","errorCode":null,"errorMessage":"invalid connection ID found (%d) when attempting to kill the connection executing post copy actions","messagePattern":"invalid connection ID found \\((.+?)\\) when attempting to kill the connection executing post copy actions","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/vreplicator.go","lineNumber":1022,"sourceCode":"\t// to execute the actions, using a DBA connection, so that any\n\t// in-flight statement (e.g. an ALTER) is aborted and any\n\t// subsequent statement on the connection fails immediately.\n\t// If we don't do this then we could e.g. cause a PRS to fail as\n\t// the running ALTER will block setting [super_]read_only, or cause\n\t// a workflow delete to time out as the engine cannot process it\n\t// until the controller has stopped.\n\t// A failed/killed ALTER will be tried again when the copy\n\t// phase starts up again on the (new) PRIMARY.\n\tdone := make(chan struct{})\n\tdefer close(done)\n\t// killActionsConnection is deliberately independent of which\n\t// action -- if any -- is currently executing so that a\n\t// cancellation which arrives between actions cannot be lost.\n\t// Non-SQL action types, if ever added, will need their own\n\t// interruption mechanism.\n\tkillActionsConnection := func() error {\n\t\tif connID < 1 {\n\t\t\treturn fmt.Errorf(\"invalid connection ID found (%d) when attempting to kill the connection executing post copy actions\", connID)\n\t\t}\n\t\t// The attempt is bounded: the connection setup honors the\n\t\t// context, and if the KILL query itself stalls the goroutine\n\t\t// below closes the connection, which unblocks it. We don't\n\t\t// parent this context on the ones whose cancellation got us\n\t\t// here -- they are already done -- but we keep their values.\n\t\tkillCtx, cancel := context.WithTimeout(context.WithoutCancel(stopCtx), killActionsConnectionTimeout)\n\t\tdefer cancel()\n\t\tkilldbc, err := vr.mysqld.GetDbaConnection(killCtx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to connect to the database when attempting to kill the connection executing post copy actions: %v\", err)\n\t\t}\n\t\tdefer killdbc.Close()\n\t\tgo func() {\n\t\t\t// killCtx is always cancelled when the attempt returns, so\n\t\t\t// this goroutine cannot leak. Close is idempotent and safe\n\t\t\t// to call concurrently with an in-flight query.\n\t\t\t<-killCtx.Done()","sourceCodeStart":1004,"sourceCodeEnd":1040,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go#L1004-L1040","documentation":"When the VReplication engine is closing or the workflow controller is stopping, a monitoring goroutine KILLs the MySQL connection running post copy actions using a saved connection ID. This error is returned if the saved connID is less than 1, meaning no valid connection ID was captured, so the KILL cannot be safely issued. It is a defensive check that should not fire since connID is validated before being stored.","triggerScenarios":"killActionsConnection is invoked after stopCtx/vre ctx cancellation while connID < 1 — only possible if the connection_id() validation was bypassed or state was corrupted; in normal code paths connID is guaranteed >= 1 before this closure is reachable.","commonSituations":"Essentially an internal invariant violation; would indicate a code path regression or corrupted state rather than a user/config problem.","solutions":["Retry the workflow restart — the interruption path is best-effort and a failed kill is logged while the action completes or is retried later","Check tablet logs for preceding 'unexpected result ... from connection_id() query' errors indicating how connID became invalid","Upgrade Vitess if running an affected version; report the log sequence as a bug","As a workaround, manually KILL the long-running ALTER on MySQL to unblock PRS/workflow delete"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// connID is validated before use; guard your own KILL helper the same way\nif connID < 1 {\n    return fmt.Errorf(\"refusing to KILL: invalid connection id %d\", connID)\n}","typeGuard":"func killableConnID(id int64) bool { return id >= 1 }","tryCatchPattern":"if err := killActionsConnection(); err != nil {\n    log.Error(\"Failed to kill the connection executing post copy actions\",\n        slog.String(\"table\", tableName), slog.Any(\"error\", err))\n    // non-fatal: action completes or is retried on restart\n}","preventionTips":["Treat a failed KILL as best-effort: the interrupted operation (PRS, workflow delete) can be retried","Check logs for preceding connection_id() anomalies that produced the invalid ID","Manually KILL the long-running ALTER on MySQL to unblock operations if needed","Report the log sequence as a bug — this path is an internal invariant check"],"tags":["vreplication","mysql","go"],"backgroundTag":"invalid-connection-id","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}