{"record":{"id":"52e2f37d025f1024","repo":"crowdsecurity/crowdsec","slug":"failed-to-register-custom-tls-config-w","errorCode":null,"errorMessage":"failed to register custom TLS config: %w","messagePattern":"failed to register custom TLS config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csconfig/database.go","lineNumber":194,"sourceCode":"\t\t\t\treturn \"\", fmt.Errorf(\"failed to append CA cert file %s: %w\", d.SSLCACert, err)\n\t\t\t}\n\t\t\tparams.Set(\"tls\", \"custom\")\n\t\t}\n\n\t\tif d.SSLClientCert != \"\" && d.SSLClientKey != \"\" {\n\t\t\tcert, err := tls.LoadX509KeyPair(d.SSLClientCert, d.SSLClientKey)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to load client cert/key pair: %w\", err)\n\t\t\t}\n\t\t\ttlsConfig.Certificates = []tls.Certificate{cert}\n\t\t\tparams.Set(\"tls\", \"custom\")\n\t\t}\n\n\t\tif params.Get(\"tls\") == \"custom\" {\n\t\t\t// Register the custom TLS config\n\t\t\terr := mysql.RegisterTLSConfig(\"custom\", tlsConfig)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to register custom TLS config: %w\", err)\n\t\t\t}\n\t\t}\n\t\tconnString = fmt.Sprintf(\"%s?%s\", connString, params.Encode())\n\tcase \"postgres\", \"postgresql\", \"pgx\":\n\t\tif d.isSocketConfig() {\n\t\t\tconnString = fmt.Sprintf(\"host=%s user=%s dbname=%s password=%s\", d.DbPath, d.User, d.DbName, d.Password)\n\t\t} else {\n\t\t\tconnString = fmt.Sprintf(\"host=%s port=%d user=%s dbname=%s password=%s\", d.Host, d.Port, d.User, d.DbName, d.Password)\n\t\t}\n\n\t\tif d.SSLMode != \"\" {\n\t\t\tconnString = fmt.Sprintf(\"%s sslmode=%s\", connString, d.SSLMode)\n\t\t}\n\n\t\tif d.SSLCACert != \"\" {\n\t\t\tconnString = fmt.Sprintf(\"%s sslrootcert=%s\", connString, d.SSLCACert)\n\t\t}\n","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csconfig/database.go#L176-L212","documentation":"Connection dsn generation in pkg/csconfig registers a user-provided custom TLS configuration with the go-sql-driver/mysql driver via mysql.RegisterTLSConfig(\"custom\", tlsConfig). The driver validates the *tls.Config (nil pointers in Certificates, invalid key pairs, etc.) and returns an error, which is wrapped here. Without a successfully registered TLS config the 'custom' TLS DSN parameter cannot resolve and the MySQL connection cannot be established securely.","triggerScenarios":"Database config has type mysql with tls=custom in the DSN params, and the built *tls.Config is invalid — e.g. CertPath/KeyPath point to mismatched or malformed PEM files so tls.X509KeyPair fails inside the driver's registration validation.","commonSituations":"Users set tls_discovery_cmd or custom CA/cert/key paths in crowdsec.db.yaml with typos, pass an encrypted private key, or provide a cert/key pair that does not match; the driver rejects the config at registration time before any connection is attempted.","solutions":["Verify the CA cert, client cert and key files exist, are valid PEM, and the cert and key match (compare modulus or use `openssl x509 -noout -modulus` vs `openssl rsa -noout -modulus`).","If the private key is passphrase-protected, decrypt it first: `openssl rsa -in key.pem -out key-nopass.pem`.","Check the mysql/tls section of the database config for wrong paths and fix them.","If TLS is not actually needed, remove the tls=custom parameter rather than registering an incomplete config."],"exampleFix":"// before (mismatched cert/key files in config)\n// after\n$ openssl x509 -noout -modulus -in client.crt | openssl md5\n$ openssl rsa  -noout -modulus -in client.key | openssl md5\n# fix the paths in /etc/crowdsec/local/database.yaml so both point to a matching pair","handlingStrategy":"validation","validationCode":"certPEM, err := os.ReadFile(cfg.CertPath)\nif err != nil { return err }\nkeyPEM, err := os.ReadFile(cfg.KeyPath)\nif err != nil { return err }\nif _, err := tls.X509KeyPair(certPEM, keyPEM); err != nil {\n    return fmt.Errorf(\"cert/key mismatch or invalid PEM: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := NewClient(ctx, dbCfg); err != nil {\n    var pathErr *fs.PathError\n    if errors.As(err, &pathErr) || strings.Contains(err.Error(), \"failed to register custom TLS config\") {\n        // fall back to non-custom TLS or surface a clear config error\n    }\n}","preventionTips":["Validate cert/key pairs with openssl before pointing crowdsec at them.","Never commit passphrase-protected keys for use with the custom TLS config.","Document the exact CA/cert/key paths in one place to avoid drift between environments."],"tags":["mysql","tls","config","database"],"backgroundTag":"invalid-config-value","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}