golang/go · critical · CertificateVerificationError
server's certificate is not allowed in FIPS 140-3 mode
Error message
server's certificate is not allowed in FIPS 140-3 mode
What it means
Thrown when FIPS 140-3 mode is active (fips140tls.Required() returns true) and the server's leaf certificate uses algorithms or key types not on the FIPS 140-3 approved list. The error is wrapped in a CertificateVerificationError with UnverifiedCertificates set.
Source
Thrown at src/crypto/tls/handshake_client.go:1179
for _, cert := range certs[1:] {
opts.Intermediates.AddCert(cert)
}
chains, err := certs[0].Verify(opts)
if err != nil {
c.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
c.verifiedChains, err = fipsAllowedChains(chains)
if err != nil {
c.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
}
if fips140tls.Required() && !isCertificateAllowedFIPS(certs[0]) {
c.sendAlert(alertBadCertificate)
err := errors.New("server's certificate is not allowed in FIPS 140-3 mode")
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
switch certs[0].PublicKey.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
case *mldsa.PublicKey:
if c.vers < VersionTLS13 {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: server's certificate uses ML-DSA, which requires TLS 1.3")
}
default:
c.sendAlert(alertUnsupportedCertificate)
return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
}
c.peerCertificates = certs
if c.config.VerifyPeerCertificate != nil && !echRejected {View on GitHub (pinned to b6b368adc5)
Solutions
- Identify which certificate property violates FIPS — check the leaf cert's key type, curve, signature hash algorithm, and key size.
- Replace the server certificate with one using FIPS-approved algorithms: RSA (2048+ bits), ECDSA P-256/P-384, SHA-256 or stronger.
- If FIPS compliance is not actually required for this connection, disable FIPS-only mode in the build or runtime configuration.
- Verify with: openssl x509 -in cert.pem -text to inspect the certificate's algorithm details.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before connecting, verify FIPS mode requirement and server cert algorithm
if fips140tls.Required() {
// Pre-fetch and inspect the server certificate
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
if err == nil {
tlsConn := tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
if err := tlsConn.Handshake(); err == nil {
certs := tlsConn.ConnectionState().PeerCertificates
if len(certs) > 0 && !isCertificateAllowedFIPS(certs[0]) {
log.Printf("server cert uses non-FIPS algorithm: %s", certs[0].PublicKeyAlgorithm)
}
}
tlsConn.Close()
}
} Try / catch
// FIPS cert errors are wrapped in CertificateVerificationError
conn, err := tls.Dial("tcp", addr, config)
if err != nil {
var certErr *tls.CertificateVerificationError
if errors.As(err, &certErr) {
if strings.Contains(certErr.Err.Error(), "FIPS 140-3") {
log.Printf("server cert not FIPS-compliant: %v", certErr.Err)
// Replace server cert or disable FIPS mode
}
}
} Prevention
- Ensure server certificates use FIPS-approved algorithms (RSA 2048+, ECDSA P-256/P-384, SHA-256+) before deploying in FIPS environments.
- Document FIPS requirements in infrastructure configuration.
- Use FIPS-validated certificate authorities for all production certificates.
When it happens
Trigger: Triggered after successful chain verification when fips140tls.Required() is true and isCertificateAllowedFIPS(certs[0]) returns false. The check applies to the leaf certificate's public key type and signature algorithm.
Common situations: Running a Go binary built with GOEXPERIMENT=fips140tls or in a FIPS-enabled environment. Server certificate uses algorithms not approved under FIPS 140-3 (e.g. Ed25519, certain curves, or disallowed hash functions). Mixing a FIPS-compliant Go client with a non-FIPS-compliant server infrastructure.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- crypto/des: use of DES is not allowed in FIPS 140-only mode
- crypto/des: use of TripleDES is not allowed in FIPS 140-only
- crypto/dsa: use of DSA is not allowed in FIPS 140-only mode
- crypto/ecdh: only crypto/rand.Reader is allowed in FIPS 140-
- crypto/ecdh: use of X25519 is not allowed in FIPS 140-only m
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/38c2c8ff0963e05e.
Report an issue: GitHub.