go-sql-driver/mysql · error
commands out of sync. Did you run multiple statements at…
Error message
commands out of sync. Did you run multiple statements at once?
What it means
ErrPktSyncMul is returned from readPacket (packets.go:74) when a sequence-number mismatch is detected while reassembling a multi-packet (split, payload larger than maxPacketSize) response. It is the large-payload variant of ErrPktSync: the desync happened partway through a >16 MiB result.
Solutions
- Serialize all access to a single connection; never read a result set and issue another command concurrently.
- Fully drain or Close() large result sets before starting the next operation.
- Reduce payload sizes (smaller SELECTs, paging) so responses fit in single packets.
- Increase the server max_allowed_packet only if genuinely needed; it does not fix concurrency bugs.
Example fix
// before: large SELECT reassembled while another op races on the conn
// -> ErrPktSyncMul mid-stream
// after: read the large result to completion on one conn, then proceed
conn, _ := db.Conn(ctx)
rows, _ := conn.QueryContext(ctx, "SELECT big_col FROM t")
for rows.Next() { /* consume entirely */ }
rows.Close()
conn.Close() Defensive patterns
Strategy: validation
Validate before calling
// For large results, drain them fully on a dedicated conn before doing
// anything else.
func drainLarge(ctx context.Context, db *sql.DB, q string) error {
conn, err := db.Conn(ctx)
if err != nil { return err }
defer conn.Close()
rows, err := conn.QueryContext(ctx, q)
if err != nil { return err }
defer rows.Close()
for rows.Next() { /* consume all */ }
return rows.Err()
} Type guard
func isPktSyncMul(err error) bool {
return errors.Is(err, mysql.ErrPktSyncMul)
} Try / catch
if errors.Is(err, mysql.ErrPktSyncMul) {
// a multi-packet read desynced: serialize conn access, page the large
// result, and retry on a fresh connection.
} Prevention
- Page large result sets with LIMIT instead of one giant read.
- Never run a second command on a conn mid-large-read.
- Reserve db.Conn(ctx) for sequential multi-statement flows.
When it happens
Trigger: Same root causes as ErrPktSync (concurrent use or un-drained result sets) but occurring during the read of a multi-part packet, i.e. a very large row or a result set whose individual packet exceeds 16 MiB.
Common situations: Streaming large BLOBs / LOAD DATA results while another goroutine touches the connection; a giant result set read concurrently with a health-check ping.
Related errors
- commands out of sync. You can't run this command now
- busy buffer
- invalid compressed packet: uncompressed length in header is
- MySQL server does not support required protocol 41+
- protocol error, illegal decimals value
AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07).
Data as JSON: /api/errors/492505617e152d68.
Report an issue: GitHub.
Appendix: source
Thrown at errors.go:28
import (
"errors"
"fmt"
"log"
"os"
)
// Various errors the driver might return. Can change between driver versions.
var (
ErrInvalidConn = errors.New("invalid connection")
ErrMalformPkt = errors.New("malformed packet")
ErrNoTLS = errors.New("TLS requested but server does not support TLS")
ErrCleartextPassword = errors.New("this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN")
ErrNativePassword = errors.New("this user requires mysql native password authentication")
ErrOldPassword = 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")
ErrUnknownPlugin = errors.New("this authentication plugin is not supported")
ErrOldProtocol = errors.New("MySQL server does not support required protocol 41+")
ErrPktSync = errors.New("commands out of sync. You can't run this command now")
ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?")
ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the `Config.MaxAllowedPacket`")
ErrBusyBuffer = errors.New("busy buffer")
// errBadConnNoWrite is used for connection errors where nothing was sent to the database yet.
// If this happens first in a function starting a database interaction, it should be replaced by driver.ErrBadConn
// to trigger a resend. Use mc.markBadConn(err) to do this.
// See https://github.com/go-sql-driver/mysql/pull/302
errBadConnNoWrite = errors.New("bad connection")
)
var defaultLogger = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime))
// Logger is used to log critical error messages.
type Logger interface {
Print(v ...any)
}
View on GitHub (pinned to 03d76c7e07)