slackhq/nebula · error

sshd.host_key must be provided

Error message

sshd.host_key must be provided

What it means

configSSH requires an SSH host key, given either as a PEM literal (detected by "-----BEGIN") or a filesystem path via the sshd.host_key config key. If the key is missing/empty, configuration aborts before the server can start, since an SSH server cannot operate without a host identity.

Source

Thrown at ssh.go:97

// that callers may invoke to run the configured ssh server. On
// failure, it returns nil, error.
func configSSH(l *slog.Logger, ssh *sshd.SSHServer, c *config.C) (func(), error) {
	listen := c.GetString("sshd.listen", "")
	if listen == "" {
		return nil, fmt.Errorf("sshd.listen must be provided")
	}

	_, port, err := net.SplitHostPort(listen)
	if err != nil {
		return nil, fmt.Errorf("invalid sshd.listen address: %s", err)
	}
	if port == "22" {
		return nil, fmt.Errorf("sshd.listen can not use port 22")
	}

	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

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Generate a host key (ssh-keygen -t ed25519 -f host_key) and set sshd.host_key to its path.
  2. Paste the PEM key content directly as sshd.host_key (it must contain "-----BEGIN").
  3. Verify the secret/file is mounted and the config key is populated at runtime.

Example fix

// before (config)
[sshd]
# host_key missing
// after (config)
[sshd]
host_key = "/etc/ssh/host_key"
Defensive patterns

Strategy: validation

Validate before calling

hk := cfg.GetString("sshd.host_key", "")
if hk == "" {
    return errors.New("sshd.host_key required: set a PEM literal or a key file path")
}

Try / catch

run, err := configSSH(logger, srv, c)
if err != nil {
    if strings.Contains(err.Error(), "sshd.host_key must be provided") {
        logger.Error("missing sshd.host_key; run ssh-keygen and set the config key")
        os.Exit(78)
    }
    return err
}

Prevention

When it happens

Trigger: Running with no sshd.host_key value: c.GetString("sshd.host_key", "") returns "" in ssh.go's configSSH, or the key is set to whitespace/empty quotes.

Common situations: First-time setup where no host key was generated yet; the key file path key renamed or the value left blank; secrets not mounted in a container so the config renders empty; a config loader that drops empty-valued keys.

Related errors


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