{"record":{"id":"3e8092699993f80e","repo":"nsqio/nsq","slug":"failed-to-loadx509keypair-s-s-s","errorCode":null,"errorMessage":"failed to LoadX509KeyPair %s, %s - %s","messagePattern":"failed to LoadX509KeyPair (.+?), (.+?) - (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nsqadmin/nsqadmin.go","lineNumber":66,"sourceCode":"\tif len(opts.NSQDHTTPAddresses) != 0 && len(opts.NSQLookupdHTTPAddresses) != 0 {\n\t\treturn nil, errors.New(\"use --nsqd-http-address or --lookupd-http-address not both\")\n\t}\n\n\tif opts.HTTPClientTLSCert != \"\" && opts.HTTPClientTLSKey == \"\" {\n\t\treturn nil, errors.New(\"--http-client-tls-key must be specified with --http-client-tls-cert\")\n\t}\n\n\tif opts.HTTPClientTLSKey != \"\" && opts.HTTPClientTLSCert == \"\" {\n\t\treturn nil, errors.New(\"--http-client-tls-cert must be specified with --http-client-tls-key\")\n\t}\n\n\tn.httpClientTLSConfig = &tls.Config{\n\t\tInsecureSkipVerify: opts.HTTPClientTLSInsecureSkipVerify,\n\t}\n\tif opts.HTTPClientTLSCert != \"\" && opts.HTTPClientTLSKey != \"\" {\n\t\tcert, err := tls.LoadX509KeyPair(opts.HTTPClientTLSCert, opts.HTTPClientTLSKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to LoadX509KeyPair %s, %s - %s\",\n\t\t\t\topts.HTTPClientTLSCert, opts.HTTPClientTLSKey, err)\n\t\t}\n\t\tn.httpClientTLSConfig.Certificates = []tls.Certificate{cert}\n\t}\n\tif opts.HTTPClientTLSRootCAFile != \"\" {\n\t\ttlsCertPool := x509.NewCertPool()\n\t\tcaCertFile, err := os.ReadFile(opts.HTTPClientTLSRootCAFile)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read TLS root CA file %s - %s\",\n\t\t\t\topts.HTTPClientTLSRootCAFile, err)\n\t\t}\n\t\tif !tlsCertPool.AppendCertsFromPEM(caCertFile) {\n\t\t\treturn nil, fmt.Errorf(\"failed to AppendCertsFromPEM %s\", opts.HTTPClientTLSRootCAFile)\n\t\t}\n\t\tn.httpClientTLSConfig.RootCAs = tlsCertPool\n\t}\n\n\tfor _, address := range opts.NSQLookupdHTTPAddresses {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/nsqadmin/nsqadmin.go#L48-L84","documentation":"During nsqadmin startup (New in nsqadmin/nsqadmin.go), when both --http-client-tls-cert and --http-client-tls-key are set, tls.LoadX509KeyPair parses both PEM files to build the client certificate nsqadmin will present to nsqd/nsqlookupd HTTPS endpoints. Any parse failure — unreadable file, missing PRIVATE KEY block, cert/key mismatch, or encrypted key needing a passphrase (not supported here) — returns 'failed to LoadX509KeyPair %s, %s - %s' naming both paths and the crypto/tls cause, and nsqadmin exits.","triggerScenarios":"Configuring nsqadmin with a cert file that is not PEM, a key file that is actually the certificate or a CSR, a key generated for a different certificate, or a passphrase-protected key (LoadX509KeyPair in this call passes no password), or a truncated/empty file from a failed secret mount.","commonSituations":"Secrets mounted wrong in k8s (empty dir instead of secret), vault templating emitting placeholders, copying the server's cert but forgetting its key, certs rotated on one path only, ops passing the CA instead of the leaf.","solutions":["Validate the pair exactly as Go will: 'openssl x509 -in cert.pem -noout -modulus | openssl md5' and 'openssl rsa -in key.pem -noout -modulus | openssl md5' — the hashes must match.","If the key is encrypted, decrypt it first: 'openssl rsa -in key.enc -out key.pem' (this code path supports no passphrase).","Confirm both files are PEM with proper BEGIN/END blocks and were mounted/rotated together.","Restart nsqadmin after fixing; it should reach 'listening on'."],"exampleFix":"# before\nnsqadmin --http-client-tls-cert=client.crt --http-client-tls-key=client.key\n# failed to LoadX509KeyPair client.crt, client.key - tls: private key does not match public key\n\n# after\nopenssl x509 -in client.crt -noout -modulus | openssl md5\nopenssl rsa -in client.key -noout -modulus | openssl md5\n# re-export a matching pair from your CA, then rerun nsqadmin","handlingStrategy":"validation","validationCode":"// pre-start: load the exact pair exactly the way nsqadmin will\nif opts.HTTPClientTLSCert != \"\" || opts.HTTPClientTLSKey != \"\" {\n    if opts.HTTPClientTLSCert == \"\" || opts.HTTPClientTLSKey == \"\" {\n        return errors.New(\"cert and key must be set together\")\n    }\n    if _, err := tls.LoadX509KeyPair(opts.HTTPClientTLSCert, opts.HTTPClientTLSKey); err != nil {\n        return fmt.Errorf(\"bad client cert pair: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"// deployment scripts: detect the class of failure from the message\nif err := startNsqadmin(cfg); err != nil && strings.Contains(err.Error(), \"failed to LoadX509KeyPair\") {\n    return errors.New(\"nsqadmin client cert/key invalid: verify PEM pair match and no passphrase\")\n}","preventionTips":["Provision cert and key as one atomic unit (same secret, same rotation).","Use unencrypted PEM keys for nsqadmin client certs.","Run an openssl modulus comparison in CI for every rotated pair."],"tags":["tls","x509","nsqadmin","configuration","startup","client-cert"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}