{"record":{"id":"9a501943d6211e7b","repo":"slackhq/nebula","slug":"error-while-reading-ca-key-s","errorCode":null,"errorMessage":"error while reading ca-key: %s","messagePattern":"error while reading ca-key: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/nebula-cert/sign.go","lineNumber":139,"sourceCode":"\t); err != nil {\n\t\treturn err\n\t}\n\tif err := reserveOutputs(&claims,\n\t\t\"out-key\", *sf.outKeyPath,\n\t\t\"out-crt\", *sf.outCertPath,\n\t\t\"out-qr\", *sf.outQRPath,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tvar curve cert.Curve\n\tvar caKey []byte\n\n\tif !isP11 {\n\t\tvar rawCAKey []byte\n\t\trawCAKey, err = readInput(\"ca-key\", *sf.caKeyPath, &claims)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error while reading ca-key: %s\", err)\n\t\t}\n\n\t\t// naively attempt to decode the private key as though it is not encrypted\n\t\tcaKey, _, curve, err = cert.UnmarshalSigningPrivateKeyFromPEM(rawCAKey)\n\t\tif errors.Is(err, cert.ErrPrivateKeyEncrypted) {\n\t\t\tvar passphrase []byte\n\t\t\tpassphrase = []byte(os.Getenv(\"NEBULA_CA_PASSPHRASE\"))\n\t\t\tif len(passphrase) == 0 {\n\t\t\t\t// ask for a passphrase until we get one\n\t\t\t\tfor i := 0; i < 5; i++ {\n\t\t\t\t\terrOut.Write([]byte(\"Enter passphrase: \"))\n\t\t\t\t\tpassphrase, err = pr.ReadPassword()\n\n\t\t\t\t\tif errors.Is(err, ErrNoTerminal) {\n\t\t\t\t\t\treturn fmt.Errorf(\"ca-key is encrypted and must be decrypted interactively\")\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"error reading password: %s\", err)\n\t\t\t\t\t}","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cmd/nebula-cert/sign.go#L121-L157","documentation":"signCert reads the CA private key via readInput(\"ca-key\", *sf.caKeyPath, &claims) and wraps any read failure with this message. It means the CA key file (or stdin payload) could not be loaded at all — before any decryption is attempted — so signing cannot proceed.","triggerScenarios":"`nebula-cert sign -ca-key /path/ca.key ...` where the ca-key file is missing, unreadable (permissions), empty, or in stdio mode the key was not provided on stdin","commonSituations":"wrong -ca-key path; key file lost or not copied to the signing host; permissions changed after provisioning; running in CI without piping the key into stdin","solutions":["Check the file exists at the -ca-key path (ls -l)","Fix read permissions on the CA key (chmod/chown or run as the owning user)","Supply the key on stdin when using stdio mode","Point -ca-key at the correct original CA key rather than a public/derived file"],"exampleFix":"// before\nnebula-cert sign -ca-key ./ca.key ...   # file actually at ./pki/ca.key\n// after\nnebula-cert sign -ca-key ./pki/ca.key ...","handlingStrategy":"validation","validationCode":"st, err := os.Stat(*sf.caKeyPath)\nif err != nil { return fmt.Errorf(\"ca-key missing: %w\", err) }\nif st.IsDir() || st.Size() == 0 { return fmt.Errorf(\"ca-key %q is empty\", *sf.caKeyPath) }\nif f, err := os.Open(*sf.caKeyPath); err == nil { f.Close() }","typeGuard":null,"tryCatchPattern":"if err := signCert(args, out, errOut, StdinPasswordReader{}); err != nil {\n    if strings.HasPrefix(err.Error(), \"error while reading ca-key\") {\n        log.Fatalf(\"check -ca-key %q exists and is readable: %v\", *sf.caKeyPath, err)\n    }\n}","preventionTips":["Verify the -ca-key path exists before invoking sign","Keep CA key permissions consistent (owned by the signing user)","In CI/stdio mode, always pipe the key into stdin","Back up the original CA key path used at creation"],"tags":["filesystem","file-read","ca-key","nebula-cert"],"backgroundTag":"file-not-found","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}