{"record":{"id":"8ff8e6f34f63d48d","repo":"golang/go","slug":"tls-no-certificates-configured","errorCode":null,"errorMessage":"tls: no certificates configured","messagePattern":"tls: no certificates configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/common.go","lineNumber":1331,"sourceCode":"\tsupportedVersions := c.supportedVersions(isClient, isQUIC)\n\tfor _, v := range supportedVersions {\n\t\tif slices.Contains(peerVersions, v) {\n\t\t\treturn v, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// errNoCertificates should be an internal detail,\n// but widely used packages access it using linkname.\n// Notable members of the hall of shame include:\n//   - github.com/xtls/xray-core\n//\n// Do not remove or change the type signature.\n// See go.dev/issue/67401.\n//\n//go:linkname errNoCertificates\nvar errNoCertificates = errors.New(\"tls: no certificates configured\")\n\n// getCertificate returns the best certificate for the given ClientHelloInfo,\n// defaulting to the first element of c.Certificates.\nfunc (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {\n\tif c.GetCertificate != nil &&\n\t\t(len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {\n\t\tcert, err := c.GetCertificate(clientHello)\n\t\tif cert != nil || err != nil {\n\t\t\treturn cert, err\n\t\t}\n\t}\n\n\tif len(c.Certificates) == 0 {\n\t\treturn nil, errNoCertificates\n\t}\n\n\tif len(c.Certificates) == 1 {\n\t\t// There's only one choice, so no point doing any work.","sourceCodeStart":1313,"sourceCodeEnd":1349,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/common.go#L1313-L1349","documentation":"errNoCertificates is the sentinel returned when a TLS server has no certificate to present. It is a package-level errors.New value (linknamed by external packages) thrown from Config.getCertificate when no Certificates and no GetCertificate callback yields a cert. Without a certificate the server cannot authenticate.","triggerScenarios":"A tls.Listener or http.Server with TLSConfig that has an empty Certificates slice and no GetCertificate/GetConfigForClient callback, receiving a ClientHello that names no SNI the server can map to a cert.","commonSituations":"Forgot to load tls.LoadX509KeyPair into Config.Certificates; config built from a template that dropped the cert field; SNI-based routing where the requested name has no matching cert; cert loaded from a path that failed silently.","solutions":["Load a key pair into Config.Certificates with tls.LoadX509KeyPair(certFile, keyFile).","Implement Config.GetCertificate to return a cert (e.g., via certmagic/autocert) for the requested SNI.","Fail fast at startup: assert len(cfg.Certificates) > 0 or GetCertificate != nil before listening.","Check that LoadX509KeyPair errors are not ignored during config setup."],"exampleFix":"// before\ncfg := &tls.Config{} // empty\ngo http.ListenAndServeTLS(\":443\", \"\", \"\", nil) // wrong: no cert files\n\n// after\ncert, err := tls.LoadX509KeyPair(\"cert.pem\", \"key.pem\")\nif err != nil { return err }\ncfg := &tls.Config{Certificates: []tls.Certificate{cert}}\nsrv := &http.Server{Addr: \":443\", TLSConfig: cfg}\nreturn srv.ListenAndServeTLS(\"\", \"\")","handlingStrategy":"validation","validationCode":"// Fail fast at startup if the server has no certificate to serve.\nfunc mustHaveCert(cfg *tls.Config) error {\n    if cfg == nil { return errors.New(\"tls config is nil\") }\n    if len(cfg.Certificates) == 0 && cfg.GetCertificate == nil {\n        return errors.New(\"tls: no certificates configured (load a key pair or set GetCertificate)\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always check the error from tls.LoadX509KeyPair before adding to Certificates.","Assert non-empty Certificates (or GetCertificate) at program start.","For SNI routing, implement GetCertificate and return an error only for truly unknown names.","Add a startup smoke test that opens the TLS listener with the real config."],"tags":["crypto","tls","server","configuration","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}