{"record":{"id":"49d8bc4213476944","repo":"slackhq/nebula","slug":"error-reading-password-s","errorCode":null,"errorMessage":"error reading password: %s","messagePattern":"error reading password: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/nebula-cert/sign.go","lineNumber":156,"sourceCode":"\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}\n\n\t\t\t\t\tif len(passphrase) > 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(passphrase) == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"cannot open encrypted ca-key without passphrase\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurve, caKey, _, err = cert.DecryptAndUnmarshalSigningPrivateKey(passphrase, rawCAKey)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error while parsing encrypted ca-key: %s\", err)\n\t\t\t}\n\t\t} else if err != nil {\n\t\t\treturn fmt.Errorf(\"error while parsing ca-key: %s\", err)\n\t\t}\n\t}","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cmd/nebula-cert/sign.go#L138-L174","documentation":"During the encrypted-CA-key passphrase loop, if pr.ReadPassword() fails for any reason other than ErrNoTerminal, signCert wraps it as \"error reading password\". This is an error obtaining the passphrase from the password reader (StdinPasswordReader or a test-injected reader), distinct from a wrong passphrase.","triggerScenarios":"ReadPassword returns a non-ErrNoTerminal error while signCert tries to prompt up to 5 times for the encrypted CA key passphrase — e.g. stdin read failure, closed stdin mid-prompt, or a custom PasswordReader implementation returning an error","commonSituations":"stdin closed or redirected from a device that errors on read; broken pipe to the terminal; a scripted PasswordReader (in tests or wrappers) that fails; exotic terminals where raw-mode password reading is unsupported","solutions":["Ensure stdin is open and readable when the passphrase prompt appears","Run inside a working interactive terminal and type the passphrase at the prompt","Check any custom PasswordReader wiring for bugs in its ReadPassword implementation","Decrypt the CA key ahead of time to avoid the prompt path entirely"],"exampleFix":"// before\nnebula-cert sign -ca-key enc.key < /dev/null   # stdin closed: ReadPassword errors\n// after\nnebula-cert sign -ca-key enc.key               # interactive stdin available","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stdin.Stat(); err != nil {\n    return fmt.Errorf(\"stdin unusable for passphrase prompt: %w\", err)\n}\nif fi, _ := os.Stdin.Stat(); fi.Mode()&os.ModeCharDevice == 0 && !allowPrompt {\n    return fmt.Errorf(\"stdin not interactive; cannot read password\")\n}","typeGuard":null,"tryCatchPattern":"if err := signCert(args, out, errOut, StdinPasswordReader{}); err != nil {\n    if strings.Contains(err.Error(), \"error reading password\") {\n        log.Printf(\"passphrase read failed: %v; ensure stdin is open and interactive\", err)\n    }\n}","preventionTips":["Never run encrypted-key signing with stdin pointed at /dev/null or a closed pipe","Test the password prompt path in the same environment used for production runs","Audit custom PasswordReader implementations for read errors","Prefer decrypting the CA key ahead of time to skip the prompt entirely"],"tags":["password","stdin","encryption","ca-key","nebula-cert"],"backgroundTag":"password-read-failed","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"}