slackhq/nebula · error
out-key must be encrypted interactively
Error message
out-key must be encrypted interactively
What it means
The nebula-cert ca command, when -encrypt is given, reads a passphrase interactively from the terminal. If the passphrase reader reports ErrNoTerminal (stdin is not a TTY), the command aborts with "out-key must be encrypted interactively" because encrypted key output requires a human at a terminal.
Source
Thrown at cmd/nebula-cert/ca.go:229
var claims ioClaims
if err := reserveOutputs(&claims,
"out-key", *cf.outKeyPath,
"out-crt", *cf.outCertPath,
"out-qr", *cf.outQRPath,
); err != nil {
return err
}
var passphrase []byte
if !isP11 && *cf.encryption {
passphrase = []byte(os.Getenv("NEBULA_CA_PASSPHRASE"))
if len(passphrase) == 0 {
for i := 0; i < 5; i++ {
errOut.Write([]byte("Enter passphrase: "))
passphrase, err = pr.ReadPassword()
if err == ErrNoTerminal {
return fmt.Errorf("out-key must be encrypted interactively")
} else if err != nil {
return fmt.Errorf("error reading passphrase: %s", err)
}
if len(passphrase) > 0 {
break
}
}
if len(passphrase) == 0 {
return fmt.Errorf("no passphrase specified, remove -encrypt flag to write out-key in plaintext")
}
}
}
var curve cert.Curve
var pub, rawPriv []byte
var p11Client *pkclient.PKClientView on GitHub (pinned to dd8f660c0a)
Solutions
- Run the command in an interactive terminal (allocate a TTY: docker run -it, ssh -t).
- Drop the -encrypt flag so the out-key is written in plaintext (then protect the file yourself).
- Use a non-interactive alternative such as generating the key programmatically with the cert library and encrypting it yourself.
- Check nebula-cert's version for a -quiet-passphrase/non-interactive passphrase flag if automation requires encryption.
Example fix
// before (CI script, no TTY) nebula-cert ca -name "ca" -encrypt // after docker exec -it ca-container nebula-cert ca -name "ca" -encrypt // or, without a TTY: nebula-cert ca -name "ca" # plaintext out-key
Defensive patterns
Strategy: validation
Validate before calling
// before invoking nebula-cert with -encrypt, ensure a TTY exists
if fi, _ := os.Stdin.Stat(); (fi.Mode() & os.ModeCharDevice) == 0 {
return fmt.Errorf("-encrypt requires an interactive terminal")
} Try / catch
out, err := exec.Command("nebula-cert", "ca", "-encrypt", ...).CombinedOutput()
if err != nil && strings.Contains(string(out), "out-key must be encrypted interactively") {
// retry with a TTY (docker -it / ssh -t) or without -encrypt
return err
} Prevention
- Never run nebula-cert ca -encrypt from cron/CI without a TTY.
- Use docker run -it or ssh -t when container/remote execution is needed.
- Drop -encrypt and secure the plaintext key file when automation is unavoidable.
When it happens
Trigger: Running `nebula-cert ca -encrypt` with stdin redirected, piped, or from a non-interactive context (cron, CI, Docker without -t) so the password reader returns ErrNoTerminal on the first prompt attempt.
Common situations: Automating CA generation in CI pipelines, scripting nebula-cert with echo'd passphrases, running inside a container without a TTY, or using SSH without -t.
Related errors
- error reading passphrase: %s
- no passphrase specified, remove -encrypt flag to write out-k
- error while encrypting out-key: %s
- ca-key is encrypted and must be decrypted interactively
- invalid passphrase or corrupt private key
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/26dd62375d19ba11.
Report an issue: GitHub.