slackhq/nebula · error

error while adding sshd.host_key: %s

Error message

error while adding sshd.host_key: %s

What it means

After loading the host key bytes, configSSH passes them to ssh.SetHostKey. If the sshd library cannot parse or accept the key (bad format, unsupported type, corrupt data), the failure is wrapped as "error while adding sshd.host_key". The file was read successfully, but its content is not a usable SSH host key.

Source

Thrown at ssh.go:112

	hostKeyPathOrKey := c.GetString("sshd.host_key", "")
	if hostKeyPathOrKey == "" {
		return nil, fmt.Errorf("sshd.host_key must be provided")
	}

	var hostKeyBytes []byte
	if strings.Contains(hostKeyPathOrKey, "-----BEGIN") {
		hostKeyBytes = []byte(hostKeyPathOrKey)
	} else {
		hostKeyBytes, err = os.ReadFile(hostKeyPathOrKey)
		if err != nil {
			return nil, fmt.Errorf("error while loading sshd.host_key file: %s", err)
		}
	}

	err = ssh.SetHostKey(hostKeyBytes)
	if err != nil {
		return nil, fmt.Errorf("error while adding sshd.host_key: %s", err)
	}

	// Clear existing trusted CAs and authorized keys
	ssh.ClearTrustedCAs()
	ssh.ClearAuthorizedKeys()

	rawCAs := c.GetStringSlice("sshd.trusted_cas", []string{})
	for _, caAuthorizedKey := range rawCAs {
		err := ssh.AddTrustedCA(caAuthorizedKey)
		if err != nil {
			l.Warn("SSH CA had an error, ignoring", "error", err, "sshCA", caAuthorizedKey)
			continue
		}
	}

	rawKeys := c.Get("sshd.authorized_users")
	keys, ok := rawKeys.([]any)
	if ok {

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Regenerate the key with ssh-keygen -t ed25519 -m PEM -f host_key and use the private key file.
  2. Validate the file content (ssh-keygen -y -f host_key) to confirm it parses as a private key.
  3. Check that SetHostKey in the vendored sshd library supports your key format and re-export accordingly.

Example fix

// before
host_key = "/etc/ssh/host_key.pub" // public key, unparseable
// after
host_key = "/etc/ssh/host_key" // ed25519 private key in PEM
Defensive patterns

Strategy: validation

Validate before calling

b, err := os.ReadFile(keyPath)
if err != nil {
    return err
}
if _, err := ssh.ParseRawPrivateKey(b); err != nil {
    return fmt.Errorf("sshd.host_key is not a parseable private key: %w", err)
}

Try / catch

run, err := configSSH(logger, srv, c)
if err != nil {
    if strings.Contains(err.Error(), "error while adding sshd.host_key") {
        logger.Error("sshd.host_key content rejected by SetHostKey; regenerate the key")
        os.Exit(78)
    }
    return err
}

Prevention

When it happens

Trigger: ssh.SetHostKey(hostKeyBytes) returns an error in ssh.go's configSSH — e.g. the file contains a public key, an encrypted/unparseable PEM, invalid DER, or an empty/whitespace file.

Common situations: Pointing sshd.host_key at a .pub file; keys generated with formats the library doesn't support (e.g. new OpenSSH encapsulation the parser rejects); a truncated download; editing the key file and corrupting the base64 body.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/16d14c38df32eeb6. Report an issue: GitHub.