{"record":{"id":"da9524086f4726fb","repo":"golang/go","slug":"client-s-certificate-is-not-allowed-in-fips-140-3","errorCode":null,"errorMessage":"client's certificate is not allowed in FIPS 140-3 mode","messagePattern":"client's certificate is not allowed in FIPS 140-3 mode","errorType":"exception","errorClass":"CertificateVerificationError","httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_server.go","lineNumber":1008,"sourceCode":"\t\t\t}\n\t\t\treturn &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}\n\t\t}\n\n\t\tc.verifiedChains, err = fipsAllowedChains(chains)\n\t\tif err != nil {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\treturn &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}\n\t\t}\n\t}\n\n\tc.peerCertificates = certs\n\tc.ocspResponse = certificate.OCSPStaple\n\tc.scts = certificate.SignedCertificateTimestamps\n\n\tif len(certs) > 0 {\n\t\tif fips140tls.Required() && !isCertificateAllowedFIPS(certs[0]) {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\terr := errors.New(\"client's certificate is not allowed in FIPS 140-3 mode\")\n\t\t\treturn &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}\n\t\t}\n\n\t\tswitch certs[0].PublicKey.(type) {\n\t\tcase *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:\n\t\tcase *mldsa.PublicKey:\n\t\t\tif c.vers < VersionTLS13 {\n\t\t\t\tc.sendAlert(alertIllegalParameter)\n\t\t\t\treturn errors.New(\"tls: client certificate uses ML-DSA, which requires TLS 1.3\")\n\t\t\t}\n\t\tdefault:\n\t\t\tc.sendAlert(alertUnsupportedCertificate)\n\t\t\treturn fmt.Errorf(\"tls: client certificate contains an unsupported public key of type %T\", certs[0].PublicKey)\n\t\t}\n\t}\n\n\tif c.config.VerifyPeerCertificate != nil {\n\t\tif err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {","sourceCodeStart":990,"sourceCodeEnd":1026,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_server.go#L990-L1026","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// Reissue client cert with FIPS-approved parameters\n// Key: ECDSA P-256 (or RSA 2048+)\n// Signature: SHA256withECDSA (or SHA256withRSA)\n\n// openssl example:\n// openssl ecparam -name prime256v1 -genkey -noout -out client.key\n// openssl req -new -x509 -key client.key -out client.crt -sha256","handlingStrategy":"validation","validationCode":"// Validate client cert against FIPS-allowed algorithms before relying on it.\n// (On the server side this happens automatically; on the issuing side, use\n// FIPS-approved parameters at generation time.)\nfunc isFIPSApprovedCert(c *x509.Certificate) bool {\n    switch k := c.PublicKey.(type) {\n    case *rsa.PublicKey:\n        return k.N.BitLen() >= 2048\n    case *ecdsa.PublicKey:\n        return k.Curve == elliptic.P256() || k.Curve == elliptic.P384()\n    }\n    return false // adjust per your Go toolchain's FIPS list\n}","typeGuard":null,"tryCatchPattern":"// Server in FIPS mode: catch and reject with a clear message.\nif err != nil && strings.Contains(err.Error(), \"not allowed in FIPS 140-3 mode\") {\n    return fmt.Errorf(\"client cert non-FIPS-compliant: %w\", err)\n}","preventionTips":["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."],"tags":["tls","server-handshake","fips140","fips","client-certificate","compliance","certificate-verification"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}