{"id":"7e964416937ec691","repo":"go-sql-driver/mysql","slug":"commands-out-of-sync-you-can-t-run-this-command-n","errorCode":null,"errorMessage":"commands out of sync. You can't run this command now","messagePattern":"commands out of sync\\. You can't run this command now","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":28,"sourceCode":"\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\n// Various errors the driver might return. Can change between driver versions.\nvar (\n\tErrInvalidConn       = errors.New(\"invalid connection\")\n\tErrMalformPkt        = errors.New(\"malformed packet\")\n\tErrNoTLS             = errors.New(\"TLS requested but server does not support TLS\")\n\tErrCleartextPassword = errors.New(\"this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN\")\n\tErrNativePassword    = errors.New(\"this user requires mysql native password authentication\")\n\tErrOldPassword       = errors.New(\"this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords\")\n\tErrUnknownPlugin     = errors.New(\"this authentication plugin is not supported\")\n\tErrOldProtocol       = errors.New(\"MySQL server does not support required protocol 41+\")\n\tErrPktSync           = errors.New(\"commands out of sync. You can't run this command now\")\n\tErrPktSyncMul        = errors.New(\"commands out of sync. Did you run multiple statements at once?\")\n\tErrPktTooLarge       = errors.New(\"packet for query is too large. Try adjusting the `Config.MaxAllowedPacket`\")\n\tErrBusyBuffer        = errors.New(\"busy buffer\")\n\n\t// errBadConnNoWrite is used for connection errors where nothing was sent to the database yet.\n\t// If this happens first in a function starting a database interaction, it should be replaced by driver.ErrBadConn\n\t// to trigger a resend. Use mc.markBadConn(err) to do this.\n\t// See https://github.com/go-sql-driver/mysql/pull/302\n\terrBadConnNoWrite = errors.New(\"bad connection\")\n)\n\nvar defaultLogger = Logger(log.New(os.Stderr, \"[mysql] \", log.Ldate|log.Ltime))\n\n// Logger is used to log critical error messages.\ntype Logger interface {\n\tPrint(v ...any)\n}\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/errors.go#L10-L46","documentation":"ErrPktSync is returned by readPacket (packets.go:115) when a packet's sequence number does not match the expected value for a non-split (single-part) packet. MySQL numbers packets sequentially per command; a mismatch means the client and server have desynchronized — typically from incorrect concurrent use of one connection or from leaving a previous result set partially unread.","triggerScenarios":"readPacket detects seq != mc.sequence at packets.go:67, sets invalidSequence, and after reading the final (non-split) packet returns ErrPktSync at packets.go:115 unless the packet is an error packet. Common when a *sql.Conn is shared across goroutines without locking, or when Rows from a query are not fully drained/closed before issuing the next query on the same connection.","commonSituations":"Multi-goroutine code sharing a single *sql.Conn (not the pool); forgetting rows.Close(); a buggy connection pool/multiplexer in front of MySQL; packet corruption from a flaky network/proxy.","solutions":["Use database/sql's *sql.DB pool (Query/QueryRow/Exec) so each goroutine gets its own connection; never share a single *sql.Conn across goroutines.","Always defer rows.Close() and fully consume result sets before reusing the connection.","If using *sql.Conn directly, guard it with a mutex or ensure single-threaded use per connection."],"exampleFix":"// before\nconn, _ := db.Conn(ctx)\ngo useConn(conn) // goroutine A\ngo useConn(conn) // goroutine B -> desync\n// after\ndb.QueryContext(ctx, ...) // pool hands each goroutine its own connection","handlingStrategy":"try-catch","validationCode":"// Use *sql.DB pool methods instead of sharing a *sql.Conn:\n//   db.QueryContext, db.ExecContext -- each goroutine gets its own conn.\n// Always: defer rows.Close().","typeGuard":null,"tryCatchPattern":"if errors.Is(err, mysql.ErrPktSync) {\n    // connection is poisoned; let the pool discard it, do not reuse *sql.Conn\n    return err\n}","preventionTips":["Never share a *sql.Conn across goroutines.","Always drain and close Rows.","Prefer *sql.DB pool entry points."],"tags":["protocol","concurrency","connection"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}