ginuerzh/gost · error
unknown public key for %q
Error message
unknown public key for %q
What it means
Raised by the SSH server's public key authentication callback: the client presented a public key that is not in the server's authorized key set, so the callback returns 'unknown public key for "<user>"' and the handshake fails. The Extensions map ('pubkey-fp') shows that valid keys are recorded with a SHA256 fingerprint on success.
Source
Thrown at ssh.go:897
// PublicKeyCallbackFunc is a callback function used by SSH server.
// It offers a public key for authentication.
type PublicKeyCallbackFunc func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error)
func defaultSSHPublicKeyCallback(keys map[string]bool) PublicKeyCallbackFunc {
if len(keys) == 0 {
return nil
}
return func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
if keys[string(pubKey.Marshal())] {
return &ssh.Permissions{
// Record the public key used for authentication.
Extensions: map[string]string{
"pubkey-fp": ssh.FingerprintSHA256(pubKey),
},
}, nil
}
return nil, fmt.Errorf("unknown public key for %q", c.User())
}
}
type sshNopConn struct {
session *sshSession
}
func (c *sshNopConn) Read(b []byte) (n int, err error) {
return 0, &net.OpError{Op: "read", Net: "ssh", Source: nil, Addr: nil, Err: errors.New("read not supported")}
}
func (c *sshNopConn) Write(b []byte) (n int, err error) {
return 0, &net.OpError{Op: "write", Net: "ssh", Source: nil, Addr: nil, Err: errors.New("write not supported")}
}
func (c *sshNopConn) Close() error {
return nil
}View on GitHub (pinned to a33fdbf4c9)
Solutions
- Add the client's public key (check its SHA256 fingerprint against server logs/config) to the server's authorized key set
- Verify the authenticator is pointed at the intended authorized-keys source
- Regenerate or copy the correct client keypair and retry
- Confirm the client offers the expected key (ssh -v or client logs) rather than a different default key
Example fix
// before: server only knows old-key.pub
authorizedKeys := []ssh.PublicKey{oldKey}
// after: add the client's new key
authorizedKeys := append(authorizedKeys, newClientPubKey) Defensive patterns
Strategy: validation
Validate before calling
// before connecting, confirm the client key is authorized
fp := fingerprintSHA256(pubKeyBytes) // compute locally
if !allowedFingerprints[fp] {
return fmt.Errorf("key %s is not in server authorized keys", fp)
} Try / catch
client, err := ssh.Dial("tcp", addr, &ssh.ClientConfig{
Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
})
if err != nil {
if strings.Contains(err.Error(), "unknown public key") {
return fmt.Errorf("install the client public key on the server: %w", err)
}
return err
} Prevention
- Add each client public key to the server's authorized key set before rollout
- Compare SHA256 fingerprints (as the server logs in pubkey-fp) when debugging
- Point the server authenticator at the correct authorized-keys file
- Use ssh -v (OpenSSH) or client logs to confirm which key is being offered
When it happens
Trigger: An SSH client authenticates with a public key whose fingerprint does not match any key configured in the server's authenticator (au), causing the final return of fmt.Errorf("unknown public key for %q", c.User()).
Common situations: Client using a new/rotated key not yet added to the server's authorized keys; pointing the server at the wrong authorized-keys file; key format mismatch; testing with a throwaway keypair.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/bda2295cd29eba99.
Report an issue: GitHub.