golang/go · error · CertificateVerificationError
client's certificate is not allowed in FIPS 140-3 mode
Error message
client's certificate is not allowed in FIPS 140-3 mode
What it means
FIPS 140-3 mode is enabled and the client's leaf certificate uses an algorithm or curve that is not on the FIPS-approved list (isCertificateAllowedFIPS returned false). FIPS-compliant deployments must reject non-approved client certificates; the server alerts bad_certificate and wraps the error in a CertificateVerificationError.
Source
Thrown at src/crypto/tls/handshake_server.go:1008
}
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
c.verifiedChains, err = fipsAllowedChains(chains)
if err != nil {
c.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
}
c.peerCertificates = certs
c.ocspResponse = certificate.OCSPStaple
c.scts = certificate.SignedCertificateTimestamps
if len(certs) > 0 {
if fips140tls.Required() && !isCertificateAllowedFIPS(certs[0]) {
c.sendAlert(alertBadCertificate)
err := errors.New("client's certificate is not allowed in FIPS 140-3 mode")
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
}
switch certs[0].PublicKey.(type) {
case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
case *mldsa.PublicKey:
if c.vers < VersionTLS13 {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: client certificate uses ML-DSA, which requires TLS 1.3")
}
default:
c.sendAlert(alertUnsupportedCertificate)
return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
}
}
if c.config.VerifyPeerCertificate != nil {
if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Reissue the client certificate using FIPS-approved parameters (RSA >= 2048, P-256/P-384 curves, SHA-256+ signatures).
- Verify against the FIPS 140-3 allowed algorithm list for your Go toolchain version.
- If FIPS enforcement is not actually required, recompile without the FIPS toolchain — but this changes your compliance posture.
- Track which clients present non-compliant certs and migrate them first.
Example fix
// Reissue client cert with FIPS-approved parameters // Key: ECDSA P-256 (or RSA 2048+) // Signature: SHA256withECDSA (or SHA256withRSA) // openssl example: // openssl ecparam -name prime256v1 -genkey -noout -out client.key // openssl req -new -x509 -key client.key -out client.crt -sha256
Defensive patterns
Strategy: validation
Validate before calling
// Validate client cert against FIPS-allowed algorithms before relying on it.
// (On the server side this happens automatically; on the issuing side, use
// FIPS-approved parameters at generation time.)
func isFIPSApprovedCert(c *x509.Certificate) bool {
switch k := c.PublicKey.(type) {
case *rsa.PublicKey:
return k.N.BitLen() >= 2048
case *ecdsa.PublicKey:
return k.Curve == elliptic.P256() || k.Curve == elliptic.P384()
}
return false // adjust per your Go toolchain's FIPS list
} Try / catch
// Server in FIPS mode: catch and reject with a clear message.
if err != nil && strings.Contains(err.Error(), "not allowed in FIPS 140-3 mode") {
return fmt.Errorf("client cert non-FIPS-compliant: %w", err)
} Prevention
- Issue all client certificates with FIPS-approved parameters (P-256/P-384, RSA >= 2048, SHA-256+).
- Maintain a migration tracker for non-compliant clients.
- Test FIPS compliance in CI before production rollout.
When it happens
Trigger: processCertsFromClient: fips140tls.Required() is true and isCertificateAllowedFIPS(certs[0]) is false. The client cert uses e.g. an unapproved curve (P-224, ed25519 in some configs), an RSA key < 2048 bits, or a non-FIPS signature algorithm.
Common situations: FIPS-mode server facing a client presenting an EC certificate on a non-approved curve, a small RSA key, or a post-quantum/mixed algorithm not yet FIPS-validated. Common during FIPS migration when not all clients have been upgraded.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: FIPS 140-3 requires the use of Extended Master Secret
- tls: FIPS 140-3 requires the use of Extended Master Secret
- server's certificate is not allowed in FIPS 140-3 mode
- tls: client certificate used with invalid signature algorith
- tls: invalid signature by the client certificate: {err}
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/da9524086f4726fb.
Report an issue: GitHub.