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

  1. Disable compression (remove compress=true) to confirm the issue is compression-specific; if it clears, the fault is in compression framing.
  2. Remove or fix any proxy that rewrites MySQL compressed frames.
  3. Upgrade the server/proxy to a version with correct compressed-packet length handling.
  4. 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

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


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)