go-sql-driver/mysql · error
invalid compressed packet: uncompressed length in header is
Error message
invalid compressed packet: uncompressed length in header is %d, actual %d
What it means
Returned by the compressed-protocol reader (compress.go:141) after inflating a packet whose decompressed byte count (nread) does not equal the uncompressedLength the server declared in the 7-byte compression header. It signals corruption or non-conformance in the compressed stream, which is only active when the DSN sets compress=true.
Solutions
- Disable compression (remove compress=true) to confirm the issue is compression-specific; if it clears, the fault is in compression framing.
- Remove or fix any proxy that rewrites MySQL compressed frames.
- Upgrade the server/proxy to a version with correct compressed-packet length handling.
- Check for packet loss / MTU issues truncating the compressed stream.
Example fix
// before dsn := "user:pass@tcp(mysql:3306)/db?compress=true" // -> "invalid compressed packet: ..." // after (diagnose): turn compression off dsn := "user:pass@tcp(mysql:3306)/db" // if the error disappears, the fault is in the compression path/proxy
Defensive patterns
Strategy: retry
Validate before calling
// Make compression opt-in only where the link is clean and verified; default off.
useCompress := cleanInternalLink
dsn := "user:pass@tcp(host:3306)/db"
if useCompress { dsn += "?compress=true" } Type guard
func isInvalidCompressedPacket(err error) bool {
return err != nil && strings.Contains(err.Error(), "invalid compressed packet")
} Try / catch
if isInvalidCompressedPacket(err) {
// retry without compression to isolate the fault; if it clears, the
// issue is in the compression framing/proxy.
} Prevention
- Enable compress=true only on verified, low-corruption links.
- Keep MySQL proxies fully transparent to compressed frames.
- Reproduce connection drops first with compression off.
When it happens
Trigger: Using compress=true and receiving a frame whose stated uncompressed size disagrees with the actual zlib output — truncated bytes, a buggy/intermediary re-compressor, network corruption, or a server/proxy that miscomputes the length field.
Common situations: Enabling wire compression over lossy/intercepted links; a proxy that recompresses MySQL traffic but writes wrong length headers; server versions with compression framing bugs.
Related errors
- commands out of sync. Did you run multiple statements at…
- commands out of sync. You can't run this command now
- invalid connectionAttributes value
- invalid dbname
- invalid max_allowed_packet value
AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07).
Data as JSON: /api/errors/64afcd66f29d4b21.
Report an issue: GitHub.
Appendix: source
Thrown at compress.go:141
if err != nil {
return err
}
// if payload is uncompressed, its length will be specified as zero, and its
// true length is contained in comprLength
if uncompressedLength == 0 {
c.buff.Write(comprData)
return nil
}
// use existing capacity in bytesBuf if possible
c.buff.Grow(uncompressedLength)
nread, err := zDecompress(comprData, &c.buff)
if err != nil {
return err
}
if nread != uncompressedLength {
return fmt.Errorf("invalid compressed packet: uncompressed length in header is %d, actual %d",
uncompressedLength, nread)
}
return nil
}
const minCompressLength = 150
const maxPayloadLen = maxPacketSize - 4
// writePackets sends one or some packets with compression.
// Use this instead of mc.netConn.Write() when mc.compress is true.
func (c *compIO) writePackets(packets []byte) (int, error) {
totalBytes := len(packets)
blankHeader := make([]byte, 7)
buf := &c.buff
for len(packets) > 0 {
payloadLen := min(maxPayloadLen, len(packets))
payload := packets[:payloadLen]View on GitHub (pinned to 03d76c7e07)