go-sql-driver/mysql · error

invalid max_allowed_packet value (%q): %w

Error message

invalid max_allowed_packet value (%q): %w

What it means

Thrown in connector.go:188 when the server's max_allowed_packet system variable (queried right after auth, since the DSN did not set MaxAllowedPacket) returns a value that strconv.Atoi cannot parse as an integer. The %q is the raw server value and %w wraps the underlying strconv error. The driver needs this number to size writes, so a non-numeric reply aborts the connection.

Source

Thrown at connector.go:188

	// compression is enabled after auth, not right after sending handshake response.
	if mc.capabilities&clientCompress > 0 {
		mc.compress = true
		mc.compIO = newCompIO(mc)
	}
	if mc.cfg.MaxAllowedPacket > 0 {
		mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket
	} else {
		// Get max allowed packet size
		maxap, err := mc.getSystemVar("max_allowed_packet")
		if err != nil {
			mc.Close()
			return nil, err
		}
		n, err := strconv.Atoi(maxap)
		if err != nil {
			mc.Close()
			return nil, fmt.Errorf("invalid max_allowed_packet value (%q): %w", maxap, err)
		}
		mc.maxAllowedPacket = n - 1
	}
	if mc.maxAllowedPacket < maxPacketSize {
		mc.maxWriteSize = mc.maxAllowedPacket
	}

	// Charset: character_set_connection, character_set_client, character_set_results
	if len(mc.cfg.charsets) > 0 {
		for _, cs := range mc.cfg.charsets {
			// ignore errors here - a charset may not exist
			if mc.cfg.Collation != "" {
				err = mc.exec("SET NAMES " + cs + " COLLATE " + mc.cfg.Collation)
			} else {
				err = mc.exec("SET NAMES " + cs)
			}
			if err == nil {
				break

View on GitHub (pinned to c426bd9379)

Solutions

  1. Set maxAllowedPacket in the DSN (e.g. ?maxAllowedPacket=4194304) so the driver never queries the server for it.
  2. Verify the server is a genuine MySQL and that SELECT @@max_allowed_packet returns a number via the mysql CLI.
  3. Remove proxies/routers from the path that may mangle the system-variable response.
  4. If the server genuinely can't answer, set maxAllowedPacket explicitly to a safe value for your workload.

Example fix

// before: DSN omits maxAllowedPacket, driver queries the server
// dsn := "user:pass@tcp(host:3306)/db"

// after: set it explicitly to skip the server query
dsn := "user:pass@tcp(host:3306)/db?maxAllowedPacket=4194304"
db, err := sql.Open("mysql", dsn)
Defensive patterns

Strategy: validation

Validate before calling

// set maxAllowedPacket in the DSN so the server is never queried for it
func dsnWithMaxPacket(base string, bytes int) string {
    sep := "?"
    if strings.Contains(base, "?") {
        sep = "&"
    }
    return fmt.Sprintf("%s%smaxAllowedPacket=%d", base, sep, bytes)
}

Try / catch

db, err := sql.Open("mysql", dsn)
if err := db.PingContext(ctx); err != nil {
    if strings.Contains(err.Error(), "invalid max_allowed_packet value") {
        // add maxAllowedPacket=<n> to the DSN and retry
    }
}

Prevention

When it happens

Trigger: Opening a connection whose DSN does NOT specify maxAllowedPacket, where the server's response to SELECT @@max_allowed_packet (or equivalent) is non-numeric — e.g. NULL, an empty string, or garbage from a misbehaving proxy/server. The connection setup fails before any query runs.

Common situations: A proxy/load balancer that returns a malformed response for system-variable queries; a non-MySQL-compatible server that doesn't expose max_allowed_packet; server misconfiguration; connection pooling against a flaky backend that returns a partial handshake. Setting maxAllowedPacket in the DSN sidesteps the query entirely.

Related errors


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