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 {
breakView on GitHub (pinned to c426bd9379)
Solutions
- Set maxAllowedPacket in the DSN (e.g. ?maxAllowedPacket=4194304) so the driver never queries the server for it.
- Verify the server is a genuine MySQL and that SELECT @@max_allowed_packet returns a number via the mysql CLI.
- Remove proxies/routers from the path that may mangle the system-variable response.
- 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
- Always set maxAllowedPacket explicitly in the DSN.
- Confirm SELECT @@max_allowed_packet returns a number via the mysql CLI when in doubt.
- Keep proxies out of the post-auth system-variable exchange.
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
- unsupported protocol version %d. Version %d or higher is req
- unknown collation: %q
- invalid DSN: did you forget to escape a param value?
- invalid DSN: missing the slash separating the database name
- invalid DSN: interpolateParams can not be used with unsafe c
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/c324598c419d94a5.json.
Report an issue: GitHub.