golang/go · error

tls: server sent non-zero legacy TLS compression method

Error message

tls: server sent non-zero legacy TLS compression method

What it means

Thrown in checkServerHelloOrHRR() when the TLS 1.3 ServerHello has a non-zero compression_method field. TLS 1.3 removed compression entirely (it enabled CRIME/BREACH attacks) — the legacy compression_method field must be zero.

Source

Thrown at src/crypto/tls/handshake_client_tls13.go:201

	if hs.serverHello.ocspStapling ||
		hs.serverHello.ticketSupported ||
		hs.serverHello.extendedMasterSecret ||
		hs.serverHello.secureRenegotiationSupported ||
		len(hs.serverHello.secureRenegotiation) != 0 ||
		len(hs.serverHello.alpnProtocol) != 0 ||
		len(hs.serverHello.scts) != 0 {
		c.sendAlert(alertUnsupportedExtension)
		return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
	}

	if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server did not echo the legacy session ID")
	}

	if hs.serverHello.compressionMethod != compressionNone {
		c.sendAlert(alertDecodeError)
		return errors.New("tls: server sent non-zero legacy TLS compression method")
	}

	selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
	if hs.suite != nil && selectedSuite != hs.suite {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
	}
	if selectedSuite == nil {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server chose an unconfigured cipher suite")
	}
	hs.suite = selectedSuite
	c.cipherSuite = hs.suite.id

	return nil
}

// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Server must set compression_method to 0 in all TLS 1.3 handshake messages.
  2. This is both a protocol violation and a security risk — upgrade the server software immediately.
  3. If the server cannot be upgraded, restrict client to TLS 1.2 (where compression is also disabled by default in Go).
  4. Run a TLS scanner (e.g. testssl.sh) to identify other server compliance issues.
Defensive patterns

Strategy: try-catch

Try / catch

conn, err := tls.Dial("tcp", addr, config)
if err != nil {
    if strings.Contains(err.Error(), "non-zero legacy TLS compression method") {
        // Security risk + protocol violation — fall back to TLS 1.2
        config.MaxVersion = tls.VersionTLS12
        conn, err = tls.Dial("tcp", addr, config)
    }
}

Prevention

When it happens

Trigger: Triggered when hs.serverHello.compressionMethod != compressionNone (0). The client sends alertDecodeError. The server selected a compression method, which is forbidden and a security concern.

Common situations: Server that doesn't properly implement TLS 1.3 and still tries to negotiate compression. Legacy server software with incomplete TLS 1.3 support. Security risk: TLS compression is the basis for CRIME and BREACH attacks.

Understand the failure class

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/10b75ceb8318c7c0. Report an issue: GitHub.