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

  1. Serialize all access to a single connection; never read a result set and issue another command concurrently.
  2. Fully drain or Close() large result sets before starting the next operation.
  3. Reduce payload sizes (smaller SELECTs, paging) so responses fit in single packets.
  4. 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

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


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)