{"record":{"id":"97b96bff0eed1d13","repo":"gastownhall/beads","slug":"externaldoltconfig-load-client-cert-key-w","errorCode":null,"errorMessage":"ExternalDoltConfig: load client cert/key: %w","messagePattern":"ExternalDoltConfig: load client cert/key: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configfile/external_dolt_config.go","lineNumber":136,"sourceCode":"\t\tcfg.ServerName = name\n\t}\n\n\tif c.TLSCACert != \"\" {\n\t\tpem, err := os.ReadFile(c.TLSCACert)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"ExternalDoltConfig: read TLSCACert: %w\", err)\n\t\t}\n\t\tpool := x509.NewCertPool()\n\t\tif !pool.AppendCertsFromPEM(pem) {\n\t\t\treturn nil, fmt.Errorf(\"ExternalDoltConfig: TLSCACert %q: no certificates parsed\", c.TLSCACert)\n\t\t}\n\t\tcfg.RootCAs = pool\n\t}\n\n\tif c.TLSCert != \"\" {\n\t\tcrt, err := tls.LoadX509KeyPair(c.TLSCert, c.TLSKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"ExternalDoltConfig: load client cert/key: %w\", err)\n\t\t}\n\t\tcfg.Certificates = []tls.Certificate{crt}\n\t}\n\n\treturn cfg, nil\n}\n","sourceCodeStart":118,"sourceCodeEnd":143,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/configfile/external_dolt_config.go#L118-L143","documentation":"TLSClientConfig failed to load the client certificate/key pair via tls.LoadX509KeyPair and wraps the underlying error. Common wrapped causes: file not found, permission denied, malformed PEM, or the cert and key not matching (different public keys). This is required when mutual TLS is configured with TLSCert set.","triggerScenarios":"Calling registerExternalTLSConfig -> TLSClientConfig with TLSCert/TLSKey paths pointing to missing files, unreadable keys, non-PEM content, or mismatched cert/key files.","commonSituations":"Key deployed without read permission for the service user; cert renewed but key not (or vice versa) causing mismatch; cert copied without its key; files swapped (key in TLSCert field); encrypted key with passphrase not supported by LoadX509KeyPair.","solutions":["Confirm both files exist and are readable: ls -l <cert> <key>; fix permissions (chmod 600 on the key, correct owner).","Verify cert and key match: compare `openssl x509 -noout -modulus` and `openssl rsa -noout -modulus` (or pub keys) — re-pair them if different.","Ensure each file contains valid PEM blocks and TLSCert/TLSKey are not swapped.","Remove TLSCert/TLSKey if mutual TLS is not actually required by the server."],"exampleFix":"// before\ntlsCert: \"/etc/beads/tls/client-new.pem\"  // renewed cert\ntlsKey: \"/etc/beads/tls/client-old.key\"   // stale key -> mismatch\n// after\ntlsCert: \"/etc/beads/tls/client-new.pem\"\ntlsKey: \"/etc/beads/tls/client-new.key\"","handlingStrategy":"try-catch","validationCode":"if cfg.TLSCert != \"\" && cfg.TLSKey != \"\" {\n    if _, err := tls.LoadX509KeyPair(cfg.TLSCert, cfg.TLSKey); err != nil {\n        return fmt.Errorf(\"client keypair precheck failed: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"cfg, err := extCfg.TLSClientConfig()\nif err != nil && strings.Contains(err.Error(), \"load client cert/key\") {\n    log.Fatalf(\"mTLS keypair bad (missing/unreadable/mismatched?): %v\\nverify with: openssl x509 -noout -modulus <cert> && openssl rsa -noout -modulus <key>\", err)\n}","preventionTips":["Renew cert and key together, atomically","chmod 600 private keys and ensure the service user owns them","Verify cert/key match after any rotation before restarting services"],"tags":["tls","certificates","keypair","io"],"backgroundTag":"tls-client-cert-load-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}