{"record":{"id":"dc6a8dcfe76da4b5","repo":"bytebase/bytebase","slug":"start-tls-v","errorCode":null,"errorMessage":"start TLS: %v","messagePattern":"start TLS: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/idp/ldap/ldap.go","lineNumber":108,"sourceCode":"\t\tInsecureSkipVerify: p.config.SkipTLSVerify,\n\t}\n\tswitch p.config.SecurityProtocol {\n\tcase storepb.LDAPIdentityProviderConfig_LDAPS:\n\t\turl := fmt.Sprintf(\"ldaps://%s:%d\", p.config.Host, p.config.Port)\n\t\tconn, err := ldap.DialURL(url, ldap.DialWithTLSConfig(tlsConfig))\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"dial TLS: %v\", err)\n\t\t}\n\t\treturn conn, nil\n\tcase storepb.LDAPIdentityProviderConfig_START_TLS:\n\t\turl := fmt.Sprintf(\"ldap://%s:%d\", p.config.Host, p.config.Port)\n\t\tconn, err := ldap.DialURL(url)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"dial: %v\", err)\n\t\t}\n\t\tif err := conn.StartTLS(tlsConfig); err != nil {\n\t\t\t_ = conn.Close()\n\t\t\treturn nil, errors.Errorf(\"start TLS: %v\", err)\n\t\t}\n\t\treturn conn, nil\n\tdefault:\n\t\turl := fmt.Sprintf(\"ldap://%s:%d\", p.config.Host, p.config.Port)\n\t\tconn, err := ldap.DialURL(url)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"dial: %v\", err)\n\t\t}\n\t\treturn conn, nil\n\t}\n}\n\n// Connect establishes a connection using the bind DN and bind password.\nfunc (p *IdentityProvider) Connect() (*ldap.Conn, error) {\n\tconn, err := p.dial()\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/idp/ldap/ldap.go#L90-L126","documentation":"In START_TLS mode, after the plain connection succeeds, dial upgrades it with conn.StartTLS(tlsConfig). If the TLS handshake fails, the connection is closed and the error is wrapped as 'start TLS: %v'. Common root causes are certificate trust and protocol mismatch issues on the port serving StartTLS.","triggerScenarios":"Calling Connect with SecurityProtocol START_TLS where the server's certificate is untrusted (self-signed or internal CA not in tlsConfig.RootCAs), the certificate hostname does not match config.Host, or the negotiated TLS version/ciphers are unsupported.","commonSituations":"Corporate LDAP servers with internal CA certificates not distributed to clients; expired server certificates; servers requiring TLS 1.2+ while the client offers older versions; pointing StartTLS at an LDAPS-only port.","solutions":["Load the directory server's CA certificate into the TLS config's RootCAs.","Set ServerName in the TLS config (or fix Host) so it matches the certificate.","Check the certificate expiry and renew if needed.","Align MinVersion/MaxVersion and cipher suites on the TLS config with the server's requirements.","Debug with openssl s_client -starttls ldap -connect host:389 to see the handshake failure."],"exampleFix":"// before\ntlsConfig := &tls.Config{} // no RootCAs, self-signed server cert\n// after\ntlsConfig := &tls.Config{RootCAs: caPool, ServerName: \"ldap.example.com\"}","handlingStrategy":"try-catch","validationCode":"func startTLSHandshakeOK(host string, port int, caPool *x509.CertPool) error {\n\tconn, err := net.DialTimeout(\"tcp\", fmt.Sprintf(\"%s:%d\", host, port), 5*time.Second)\n\tif err != nil { return err }\n\tdefer conn.Close()\n\ttc := tls.Client(conn, &tls.Config{RootCAs: caPool, ServerName: host})\n\treturn tc.Handshake()\n}\n// pre-flight before Connect","typeGuard":null,"tryCatchPattern":"conn, err := p.dial()\nif err != nil {\n\tif strings.Contains(err.Error(), \"start TLS\") {\n\t\treturn nil, fmt.Errorf(\"StartTLS handshake failed for %s:%d (check CA cert/hostname): %w\", p.config.Host, p.config.Port, err)\n\t}\n\treturn nil, err\n}","preventionTips":["Load the server CA into RootCAs; set ServerName to match the certificate.","Monitor certificate expiry.","Pin TLS versions/ciphers consistent with the server.","Test with openssl s_client -starttls ldap -connect host:389."],"tags":["ldap","tls","certificate"],"backgroundTag":"tls-handshake-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}