go-sql-driver/mysql · error

commands out of sync. You can't run this command now

Error message

commands out of sync. You can't run this command now

What it means

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.

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 c426bd9379)

Solutions

  1. 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.
  2. Always defer rows.Close() and fully consume result sets before reusing the connection.
  3. If using *sql.Conn directly, guard it with a mutex or ensure single-threaded use per connection.

Example fix

// before
conn, _ := db.Conn(ctx)
go useConn(conn) // goroutine A
go useConn(conn) // goroutine B -> desync
// after
db.QueryContext(ctx, ...) // pool hands each goroutine its own connection
Defensive patterns

Strategy: try-catch

Validate before calling

// Use *sql.DB pool methods instead of sharing a *sql.Conn:
//   db.QueryContext, db.ExecContext -- each goroutine gets its own conn.
// Always: defer rows.Close().

Try / catch

if errors.Is(err, mysql.ErrPktSync) {
    // connection is poisoned; let the pool discard it, do not reuse *sql.Conn
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04). Data as JSON: /data/errors/7e964416937ec691.json. Report an issue: GitHub.