golang/go · error

tls: peer doesn't support any of the certificate's signature

Error message

tls: peer doesn't support any of the certificate's signature algorithms

What it means

Thrown by selectSignatureScheme when no peer-advertised signature algorithm is also in the certificate's supported set. After filtering disabled algorithms and walking peerAlgs in preference order, no overlap was found, so the certificate cannot produce a signature the peer will accept.

Source

Thrown at src/crypto/tls/auth.go:297

	}
	if len(peerAlgs) == 0 && vers == VersionTLS12 {
		// For TLS 1.2, if the client didn't send signature_algorithms then we
		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
		// RFC 9155 made signature_algorithms mandatory in TLS 1.2, and we gated
		// it behind the tlssha1 GODEBUG setting.
		if tlssha1.Value() != "1" {
			return 0, errors.New("tls: missing signature_algorithms from TLS 1.2 peer")
		}
		peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
	}
	// Pick signature scheme in the peer's preference order, as our
	// preference order is not configurable.
	for _, preferredAlg := range peerAlgs {
		if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
			return preferredAlg, nil
		}
	}
	return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
}

// unsupportedCertificateError returns a helpful error for certificates with
// an unsupported private key.
func unsupportedCertificateError(cert *Certificate) error {
	switch cert.PrivateKey.(type) {
	case rsa.PrivateKey, ecdsa.PrivateKey:
		return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
			cert.PrivateKey, cert.PrivateKey)
	case *ed25519.PrivateKey:
		return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
	}

	signer, ok := cert.PrivateKey.(crypto.Signer)
	if !ok {
		return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
			cert.PrivateKey)
	}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Provide a certificate whose key type matches an algorithm the peer advertises (e.g., add an RSA cert if peer is RSA-only).
  2. Inspect the peer's ClientHello signature_algorithms (e.g., with a TLS debug log) and align the certificate choice.
  3. Upgrade the peer to advertise modern schemes (rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256).
  4. For multi-cert setups, configure Config.GetCertificate to pick a compatible cert by ClientHelloInfo.SignatureSchemes.

Example fix

// before: only an ECDSA cert, peer advertises RSA-only
cfg.Certificates = []tls.Certificate{ecdsaCert}

// after: also offer an RSA cert and select by SNI/schemes
cfg.Certificates = []tls.Certificate{ecdsaCert, rsaCert}
cfg.GetCertificate = func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
    for _, s := range chi.SignatureSchemes {
        if isRSA(s) { return &rsaCert, nil }
    }
    return &ecdsaCert, nil
}
Defensive patterns

Strategy: fallback

Validate before calling

// Choose a certificate whose key type matches the peer's advertised schemes.
func pickCert(chi *tls.ClientHelloInfo, certs map[string]tls.Certificate) (*tls.Certificate, error) {
    for _, s := range chi.SignatureSchemes {
        switch {
        case isRSAScheme(s) && certs["rsa"] != (tls.Certificate{}):
            c := certs["rsa"]; return &c, nil
        case isECDSAScheme(s) && certs["ecdsa"] != (tls.Certificate{}):
            c := certs["ecdsa"]; return &c, nil
        }
    }
    return nil, errors.New("no cert matches peer signature schemes")
}

Prevention

When it happens

Trigger: The peer's signature_algorithms list and the algorithms usable by the configured certificate (RSA-PSS, ECDSA, Ed25519, etc.) are disjoint. Reached at the end of selectSignatureScheme.

Common situations: Certificate is ECDSA but peer only advertises RSA algorithms (or vice versa); peer only offers SHA-1 schemes which Go disabled; an RSA cert below the peer's minimum key size; misconfigured client restricting signature_algorithms too aggressively.

Understand the failure class

Related errors


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