{"record":{"id":"34b49c027b47c09a","repo":"rqlite/rqlite","slug":"cannot-create-tls-config-s","errorCode":null,"errorMessage":"cannot create TLS config: %s","messagePattern":"cannot create TLS config: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"tcp/mux.go","lineNumber":154,"sourceCode":"\t}\n\n\tmtlsState := rtls.MTLSStateDisabled\n\tif mutual {\n\t\tmtlsState = rtls.MTLSStateEnabled\n\t}\n\tmux.certReloader, err = rtls.NewCertReloader(cert, key)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create cert monitor: %s\", err)\n\t}\n\n\t// Wrap the GetCertificate function so we update the stats.\n\tgetCertFunc := func() (*tls.Certificate, error) {\n\t\tstats.Add(numTLSCertFetched, 1)\n\t\treturn mux.certReloader.GetCertificate()\n\t}\n\tmux.tlsConfig, err = rtls.CreateServerConfigWithFunc(getCertFunc, caCert, mtlsState, verifyCN)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create TLS config: %s\", err)\n\t}\n\n\tmux.ln = tls.NewListener(ln, mux.tlsConfig)\n\treturn mux, nil\n}\n\n// Serve handles connections from ln and multiplexes then across registered listener.\nfunc (mux *Mux) Serve() error {\n\ttlsStr := \"\"\n\tif mux.tlsConfig != nil {\n\t\ttlsStr = \"TLS \"\n\t}\n\tmux.Logger.Printf(\"%smux serving on %s, advertising %s\", tlsStr, mux.ln.Addr().String(), mux.addr)\n\n\tfor {\n\t\t// Wait for the next connection.\n\t\t// If it returns a temporary error then simply retry.\n\t\t// If it returns any other error then exit immediately.","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/rqlite/rqlite/blob/7586a4d1bdbd9a5a80021664c5a863cd850adb60/tcp/mux.go#L136-L172","documentation":"Returned by newTLSMux (via NewTLSMux / NewMutualTLSMux) when rtls.CreateServerConfigWithFunc fails to build the *tls.Config from the certificate reloader and CA settings. This happens after the cert reloader was created successfully, so the failure is in the CA certificate, mutual-TLS state, client-CN verification settings, or the generated config itself. Node-to-node TLS cannot be enabled without a valid config.","triggerScenarios":"Starting rqlited with mutual TLS (-node-tls-ca / -node-verify-client / -node-no-verify-hostnames variants) where the CA cert file is missing, unreadable, or not a valid certificate; or invalid CA/mTLS-state combinations.","commonSituations":"CA bundle path typo; CA file empty or not PEM; combining -node-tls-ca with mismatched mutual-TLS flags; Kubernetes secret mounts missing the ca.crt key; expired root CA being rejected by strict parsing.","solutions":["Read the wrapped error; 'no such file' or 'failed to find any PEM data' means fix the CA path/content first.","Validate the CA file: openssl x509 -in ca.pem -noout -text must parse and show a CA:TRUE basic constraint.","Ensure the mutual-TLS flag combination matches the intent (client-cert required vs optional) per rqlite TLS docs.","Restart the node after correcting the flags; confirm inter-node connectivity with the new config."],"exampleFix":"// before\nrqlited -node-tls-cert c.pem -node-tls-key k.pem -node-tls-ca /etc/rqlite/missing-ca.pem\n// cannot create TLS config: open /etc/rqlite/missing-ca.pem: no such file or directory\n// after\nrqlited -node-tls-cert c.pem -node-tls-key k.pem -node-tls-ca /etc/rqlite/ca.pem","handlingStrategy":"validation","validationCode":"caPEM, err := os.ReadFile(caCertPath)\nif err != nil { return err }\npool := x509.NewCertPool()\nif !pool.AppendCertsFromPEM(caPEM) { return errors.New(\"invalid or empty CA bundle\") }\nif !bytes.Contains(caPEM, []byte(\"BEGIN CERTIFICATE\")) { return errors.New(\"CA file is not PEM\") }","typeGuard":null,"tryCatchPattern":"mux, err := tcp.NewMutualTLSMux(ln, cert, key, caCert, verifyCN)\nif err != nil && strings.Contains(err.Error(), \"cannot create TLS config\") {\n    log.Fatalf(\"invalid TLS/CA configuration: %v\", err)\n}","preventionTips":["Validate CA bundles with openssl x509 / x509 -CAfile before rollout.","Ensure mTLS flags and CA files are provisioned together as one config unit.","Confirm Kubernetes secrets include ca.crt and it is a valid PEM cert.","Test mutual TLS between two nodes in staging before production rollout."],"tags":["tls","certificates","mutual-tls"],"backgroundTag":"tls-certificate-load-failed","analyzedSha":"7586a4d1bdbd9a5a80021664c5a863cd850adb60","analyzedAt":"2026-09-03T07:03:02.260Z","contentChangedAt":"2026-09-03T07:03:02.260Z","schemaVersion":2},"datasetVersion":"2026-09-10T12:17:11.382Z"}