golang/go · error

tls: TLS 1.3 client supports illegal compression methods

Error message

tls: TLS 1.3 client supports illegal compression methods

What it means

TLS 1.3 (RFC 8446 §4.1.2) requires the ClientHello compression_methods contain exactly one entry, the null compression method (0). Compression was removed from TLS 1.3 because of CRIME-style attacks. Any other compression list (multiple methods, DEFLATE, or empty) is illegal and the server sends illegal_parameter.

Source

Thrown at src/crypto/tls/handshake_server_tls13.go:146

	// TLS 1.2, because a TLS 1.3 server would abort here. The situation before
	// supported_versions was not better because there was just no way to do a
	// TLS 1.4 handshake without risking the server selecting TLS 1.3.
	for _, id := range hs.clientHello.cipherSuites {
		if id == TLS_FALLBACK_SCSV {
			// Use c.vers instead of max(supported_versions) because an attacker
			// could defeat this by adding an arbitrary high version otherwise.
			if c.vers < c.config.maxSupportedVersion(roleServer, c.quic != nil) {
				c.sendAlert(alertInappropriateFallback)
				return errors.New("tls: client using inappropriate protocol fallback")
			}
			break
		}
	}

	if len(hs.clientHello.compressionMethods) != 1 ||
		hs.clientHello.compressionMethods[0] != compressionNone {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: TLS 1.3 client supports illegal compression methods")
	}

	hs.hello.random = make([]byte, 32)
	if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil {
		c.sendAlert(alertInternalError)
		return err
	}

	if len(hs.clientHello.secureRenegotiation) != 0 {
		c.sendAlert(alertHandshakeFailure)
		return errors.New("tls: initial handshake had non-empty renegotiation extension")
	}

	if hs.clientHello.earlyData && c.quic != nil {
		if len(hs.clientHello.pskIdentities) == 0 {
			c.sendAlert(alertIllegalParameter)
			return errors.New("tls: early_data without pre_shared_key")
		}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Set ClientHello compression_methods to a single null (0x00) entry
  2. Use a compliant TLS library rather than constructing the ClientHello by hand

Example fix

// before
hello.compressionMethods = []byte{0x00, 0x01} // null + deflate

// after
hello.compressionMethods = []byte{0x00} // null only
Defensive patterns

Strategy: try-catch

Try / catch

if err := tlsConn.Handshake(); err != nil {
    if strings.Contains(err.Error(), "illegal compression methods") {
        log.Printf("non-compliant client (bad compression) from %v", remote)
    }
    c.Close()
    return
}

Prevention

When it happens

Trigger: The client sends compression_methods with length != 1, or with a single method that is not compressionNone (0). Occurs with non-compliant or older TLS stacks that carry TLS 1.2 compression negotiation forward.

Common situations: Hand-rolled TLS clients, old TLS libraries, fuzzers, or a TLS 1.2 client stack that always advertises compression and is being offered against a TLS 1.3 server.

Understand the failure class

Related errors


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