{"record":{"id":"76e59579dcc2049b","repo":"golang/go","slug":"tls-server-s-certificate-uses-ml-dsa-which-requi","errorCode":null,"errorMessage":"tls: server's certificate uses ML-DSA, which requires TLS 1.3","messagePattern":"tls: server's certificate uses ML-DSA, which requires TLS 1\\.3","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client.go","lineNumber":1188,"sourceCode":"\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\tif fips140tls.Required() && !isCertificateAllowedFIPS(certs[0]) {\n\t\tc.sendAlert(alertBadCertificate)\n\t\terr := errors.New(\"server's certificate is not allowed in FIPS 140-3 mode\")\n\t\treturn &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}\n\t}\n\n\tswitch certs[0].PublicKey.(type) {\n\tcase *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:\n\tcase *mldsa.PublicKey:\n\t\tif c.vers < VersionTLS13 {\n\t\t\tc.sendAlert(alertIllegalParameter)\n\t\t\treturn errors.New(\"tls: server's certificate uses ML-DSA, which requires TLS 1.3\")\n\t\t}\n\tdefault:\n\t\tc.sendAlert(alertUnsupportedCertificate)\n\t\treturn fmt.Errorf(\"tls: server's certificate contains an unsupported type of public key: %T\", certs[0].PublicKey)\n\t}\n\n\tc.peerCertificates = certs\n\n\tif c.config.VerifyPeerCertificate != nil && !echRejected {\n\t\tif err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif c.config.VerifyConnection != nil && !echRejected {\n\t\tif err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {\n\t\t\tc.sendAlert(alertBadCertificate)","sourceCodeStart":1170,"sourceCodeEnd":1206,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L1170-L1206","documentation":"Thrown in verifyServerCertificate() when the server's leaf certificate uses an ML-DSA (Module-Lattice-Based Digital Signature Algorithm) public key but the negotiated TLS version is below 1.3. ML-DSA is a post-quantum signature algorithm only defined for TLS 1.3 per the relevant specifications.","triggerScenarios":"Triggered when certs[0].PublicKey is *mldsa.PublicKey and c.vers < VersionTLS13 (0x0304). The client sends alertIllegalParameter.","commonSituations":"Client tls.Config restricts MaxVersion to TLS 1.2 while connecting to a server with a post-quantum ML-DSA certificate. Client in a restricted environment that downgrades the TLS version. Server admin deployed ML-DSA certificates without ensuring all clients support TLS 1.3.","solutions":["Remove or raise the MaxVersion restriction in tls.Config to allow TLS 1.3 negotiation.","Ensure MinVersion is not set above VersionTLS13 and MaxVersion defaults to VersionTLS13.","If TLS 1.3 is unavailable on the client, replace the server certificate with a classical algorithm (RSA, ECDSA, or Ed25519).","Verify TLS 1.3 support end-to-end: openssl s_client -connect host:443 -tls1_3"],"exampleFix":"// before — forces TLS 1.2, incompatible with ML-DSA certs\nconfig := &tls.Config{\n    MaxVersion: tls.VersionTLS12,\n}\n\n// after — allow TLS 1.3\nconfig := &tls.Config{\n    MinVersion: tls.VersionTLS12,\n    MaxVersion: tls.VersionTLS13,\n}","handlingStrategy":"validation","validationCode":"// Validate TLS version config before connecting when ML-DSA certs may be used\nfunc validateConfigForPostQuantum(config *tls.Config) error {\n    if config.MaxVersion != 0 && config.MaxVersion < tls.VersionTLS13 {\n        return fmt.Errorf(\"MaxVersion is below TLS 1.3; servers with ML-DSA certs will fail\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"conn, err := tls.Dial(\"tcp\", addr, config)\nif err != nil {\n    if strings.Contains(err.Error(), \"ML-DSA, which requires TLS 1.3\") {\n        // Raise MaxVersion to allow TLS 1.3 and retry\n        config.MaxVersion = tls.VersionTLS13\n        conn, err = tls.Dial(\"tcp\", addr, config)\n    }\n}","preventionTips":["Do not restrict MaxVersion below TLS 1.3 unless absolutely necessary.","Test TLS version negotiation with: openssl s_client -connect host:443 -tls1_3.","Document which servers use post-quantum certificates."],"tags":["tls","go","ml-dsa","post-quantum","tls13","certificate"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}