slackhq/nebula · error

unknown public key for %s (%s)

Error message

unknown public key for %s (%s)

What it means

After the user is found, the SSH authenticator compares the presented public key against the trusted keys registered for that user. If the key's fingerprint is not in the set, auth fails with 'unknown public key'. The message includes the username and the SHA256 fingerprint of the offered key to aid debugging.

Source

Thrown at sshd/server.go:74

				}
			}

			return false
		},
		UserKeyFallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
			pk := string(pubKey.Marshal())
			fp := ssh.FingerprintSHA256(pubKey)

			s.authLock.RLock()
			defer s.authLock.RUnlock()
			tk, ok := s.trustedKeys[c.User()]
			if !ok {
				return nil, fmt.Errorf("unknown user %s", c.User())
			}

			_, ok = tk[pk]
			if !ok {
				return nil, fmt.Errorf("unknown public key for %s (%s)", c.User(), fp)
			}

			return &ssh.Permissions{
				// Record the public key used for authentication.
				Extensions: map[string]string{
					"fp":   fp,
					"user": c.User(),
				},
			}, nil

		},
	}

	s.config = &ssh.ServerConfig{
		PublicKeyCallback: cc.Authenticate,
		ServerVersion:     fmt.Sprintf("SSH-2.0-Nebula???"),
	}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Add the fingerprint shown in the error message to that user's trusted keys in the nebula ssh config
  2. Force the correct key: ssh -i /path/to/trusted_key -o IdentitiesOnly=yes
  3. Verify the configured key is complete and correctly indented in the config, then reload
  4. If the key was rotated, replace the old entry with the new public key and restart/reload nebula

Example fix

// before
trusted_users:
  admin:
    - "ssh-ed25519 AAAAOLD..."
// after
trusted_users:
  admin:
    - "ssh-ed25519 AAAANEW..."
Defensive patterns

Strategy: validation

Validate before calling

# Compute the fingerprint the server will compare against and confirm it is configured
ssh-keygen -lf ~/.ssh/id_ed25519.pub   # compare with entries under trusted_users in nebula.yaml

Try / catch

try {
  sshConnect(user, keyPath)
} catch (e) {
  if (e.message.includes("unknown public key")) {
    const fp = /\(([A-Za-z0-9+/=]+)\)/.exec(e.message)?.[1]
    console.error(`key ${fp} not trusted for this user; add it to nebula config or use IdentitiesOnly`)
  }
  throw e
}

Prevention

When it happens

Trigger: SSH client authenticates to nebula's SSH debug server with a key that is not listed under that user's trusted keys in the config — wrong key file, key rotation, or agent offering an unexpected key.

Common situations: Rotated SSH keys without updating nebula config; ssh-agent offering the default key instead of the trusted one; copy/paste truncated the public key in the YAML; connecting as the right user but with a personal key not whitelisted.

Related errors


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