{"record":{"id":"b24a2c10561c8c32","repo":"golang/go","slug":"tls-missing-signature-algorithms-from-tls-1-2-pee","errorCode":null,"errorMessage":"tls: missing signature_algorithms from TLS 1.2 peer","messagePattern":"tls: missing signature_algorithms from TLS 1\\.2 peer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/auth.go","lineNumber":286,"sourceCode":"\t\tsupportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {\n\t\t\treturn !isSupportedSignatureAlgorithm(sigAlg, c.SupportedSignatureAlgorithms)\n\t\t})\n\t}\n\t// Filter out any unsupported signature algorithms, for example due to\n\t// FIPS 140-3 policy, tlssha1=0, or protocol version.\n\tsupportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {\n\t\treturn isDisabledSignatureAlgorithm(vers, sigAlg, false)\n\t})\n\tif len(supportedAlgs) == 0 {\n\t\treturn 0, unsupportedCertificateError(c)\n\t}\n\tif len(peerAlgs) == 0 && vers == VersionTLS12 {\n\t\t// For TLS 1.2, if the client didn't send signature_algorithms then we\n\t\t// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.\n\t\t// RFC 9155 made signature_algorithms mandatory in TLS 1.2, and we gated\n\t\t// it behind the tlssha1 GODEBUG setting.\n\t\tif tlssha1.Value() != \"1\" {\n\t\t\treturn 0, errors.New(\"tls: missing signature_algorithms from TLS 1.2 peer\")\n\t\t}\n\t\tpeerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}\n\t}\n\t// Pick signature scheme in the peer's preference order, as our\n\t// preference order is not configurable.\n\tfor _, preferredAlg := range peerAlgs {\n\t\tif isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {\n\t\t\treturn preferredAlg, nil\n\t\t}\n\t}\n\treturn 0, errors.New(\"tls: peer doesn't support any of the certificate's signature algorithms\")\n}\n\n// unsupportedCertificateError returns a helpful error for certificates with\n// an unsupported private key.\nfunc unsupportedCertificateError(cert *Certificate) error {\n\tswitch cert.PrivateKey.(type) {\n\tcase rsa.PrivateKey, ecdsa.PrivateKey:","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/auth.go#L268-L304","documentation":"Thrown when selecting a signature algorithm for a TLS 1.2 client that sent no signature_algorithms extension, and the tlssha1 GODEBUG is not '1'. Per RFC 9155 signature_algorithms is mandatory in TLS 1.2; Go only falls back to the old SHA-1 assumption if GODEBUG tlssha1=1 is set. Otherwise the handshake is rejected.","triggerScenarios":"Acting as a TLS 1.2 server, the ClientHello omits signature_algorithms and GODEBUG=tlssha1 is unset (default in current Go). selectSignatureScheme returns this error before signing the handshake.","commonSituations":"A very old or non-conformant client (embedded device, legacy library) that omits signature_algorithms; Go upgraded to a version that gated SHA-1 fallback behind tlssha1; server pinned to TLS 1.2 with such clients.","solutions":["Update the client to send the signature_algorithms extension (RFC 5246/9155).","If you must support the legacy client, set GODEBUG=tlssha1=1 in the environment (re-enables SHA-1 fallback).","Move the connection to TLS 1.3 where signature_algorithms is always present.","Document the SHA-1 security trade-off before enabling tlssha1."],"exampleFix":"// before: client omits signature_algorithms, server rejects\n// run with: GODEBUG unset\n\n// after (accept legacy SHA-1 client):\n//   GODEBUG=tlssha1=1 ./server\n// or prefer: fix the client to send signature_algorithms","handlingStrategy":"validation","validationCode":"// Detect a client that omits signature_algorithms before relying on SHA-1 fallback.\nfunc needsSHA1Fallback(chi *tls.ClientHelloInfo) bool {\n    return chi != nil && len(chi.SignatureSchemes) == 0\n}\n// If true and you must serve it, ensure GODEBUG=tlssha1=1 is set or reject.","typeGuard":null,"tryCatchPattern":"if err := srv.ListenAndServeTLS(\"\", \"\"); err != nil {\n    if strings.Contains(err.Error(), \"missing signature_algorithms from TLS 1.2 peer\") {\n        log.Printf(\"set GODEBUG=tlssha1=1 or upgrade the client to send signature_algorithms\")\n    }\n}","preventionTips":["Move clients to TLS 1.3 or ensure they send signature_algorithms.","Document the security implications before enabling tlssha1.","Log ClientHello signature_algorithms in staging to find non-conformant clients.","Avoid pinning servers to TLS 1.2 when supporting modern clients."],"tags":["crypto","tls","handshake","signature-algorithms","compatibility","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}