golang/go · warning

tls: client offered only incompatible point formats

Error message

tls: client offered only incompatible point formats

What it means

During ECDHE cipher selection the server found that the client's Supported Point Formats extension lists only non-uncompressed formats. RFC 8422 §5.1.2 requires uncompressed (0) support; a client offering only compressed or ansiX962 formats cannot interoperate. The error returns false (cipher rejected) rather than aborting the handshake outright.

Source

Thrown at src/crypto/tls/handshake_server.go:392

	}

	supportsPointFormat := false
	offeredNonCompressedFormat := false
	for _, pointFormat := range supportedPoints {
		if pointFormat == pointFormatUncompressed {
			supportsPointFormat = true
		} else {
			offeredNonCompressedFormat = true
		}
	}
	// Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
	// missing, uncompressed points are supported. If supportedPoints is empty,
	// the extension must be missing, as an empty extension body is rejected by
	// the parser. See https://go.dev/issue/49126.
	if len(supportedPoints) == 0 {
		supportsPointFormat = true
	} else if offeredNonCompressedFormat && !supportsPointFormat {
		return false, errors.New("tls: client offered only incompatible point formats")
	}

	return supportsCurve && supportsPointFormat, nil
}

func (hs *serverHandshakeState) pickCipherSuite() error {
	c := hs.c

	preferenceList := c.config.cipherSuites(isAESGCMPreferred(hs.clientHello.cipherSuites))

	hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
	if hs.suite == nil {
		c.sendAlert(alertHandshakeFailure)
		return fmt.Errorf("tls: no cipher suite supported by both client and server; client offered: %x",
			hs.clientHello.cipherSuites)
	}
	c.cipherSuite = hs.suite.id

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Update the client to include uncompressed (0) in its Supported Point Formats extension.
  2. If the client cannot be updated, ensure the server also offers a non-ECDHE cipher suite (e.g. plain RSA key exchange) so a fallback path exists.
  3. Note this is returned from a filter, not raised as an alert — the server falls back to other suites; if none match, expect the 'no cipher suite supported' error to follow.

Example fix

// Client fix: ensure uncompressed EC points are advertised.
// Standard TLS libraries include 0x00 by default.
// Custom encoder:
pointFormats: []byte{0x00 /* uncompressed */}
Defensive patterns

Strategy: validation

Validate before calling

// Client: ensure uncompressed (0) EC point format is advertised.
// Standard TLS libraries include it; custom encoders must add:
pointFormats := []byte{0x00 /* uncompressed */}

Try / catch

// Server: this is returned from a cipher-suite filter, not raised directly.
// Ensure at least one non-ECDHE suite is configured as fallback.
cfg := &tls.Config{CipherSuites: []uint16{
    tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    tls.TLS_RSA_WITH_AES_128_GCM_SHA256, // fallback
}}

Prevention

When it happens

Trigger: supportsECDHE inspects supportedPoints; if offeredNonCompressedFormat is true but supportsPointFormat stays false (no 0 entry), the function returns (false, error). ECDHE cipher suites are then filtered out for this client.

Common situations: A legacy or non-compliant client listing only deprecated compressed EC point formats. Modern TLS clients always include uncompressed (0), so this typically surfaces with embedded/legacy TLS stacks or fuzz inputs.

Understand the failure class

Related errors


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