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

Thrown by compIO.readCompressedPacket (compress.go:141) after zlib-decompressing a compressed packet whose resulting byte count does not match the uncompressedLength the server advertised in the 7-byte compressed header. A mismatch means the compressed stream was corrupted, truncated, or tampered with — the integrity contract of compressed mode is broken.

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

Solutions

  1. Disable compression (remove compress=true from the DSN) — for most workloads on a LAN it adds CPU cost without net benefit, and removes this entire class of error.
  2. If you need compression, rule out proxies/routers that mishandle compressed frames by connecting directly to MySQL.
  3. Check network health (packet loss, MTU mismatches, NIC errors) on the link.
  4. Upgrade the MySQL server in case of a known compression-framing bug.

Example fix

// before
dsn := "user:pass@tcp(host:3306)/db?compress=true"

// after: drop compression unless you have measured a benefit
dsn := "user:pass@tcp(host:3306)/db"
Defensive patterns

Strategy: validation

Validate before calling

// only enable compression when you have measured a benefit and the link is clean
func dsnWithCompression(base string, compress bool) string {
    if !compress {
        return strings.ReplaceAll(base, "compress=true", "")
    }
    return base
}

Try / catch

if err := rows.Err(); err != nil {
    if strings.Contains(err.Error(), "invalid compressed packet") {
        // disable compression in the DSN and reconnect
    }
}

Prevention

When it happens

Trigger: Using the driver with compression enabled (DSN parameter compress=true) over a connection where a compressed packet's declared uncompressed length disagrees with the actually decompressed size — flaky network corrupting bytes, a proxy mangling compressed frames, or a server bug in compressed-mode framing.

Common situations: compress=true across a lossy/intercepted link or through a proxy that doesn't transparently pass compressed frames; MTU/fragmentation issues truncating compressed packets; server-side compression bugs in older MySQL versions; memory pressure corrupting buffers.

Related errors


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