AlistGo/alist · error
public key refused
Error message
public key refused
What it means
Returned at the end of PublicKeyAuth after none of the SSH public keys stored for the user matches the key presented by the client. The driver fetches all keys via op.GetSSHPublicKeyByUserId and compares the marshaled key bytes; a mismatch (or unparsable stored key) causes the loop to skip the candidate, and the final statement returns 'public key refused'. This is an authentication failure, distinct from the permission check that precedes it.
Source
Thrown at server/sftp.go:130
return nil, errors.New("user is not allowed to access via SFTP")
}
keys, _, err := op.GetSSHPublicKeyByUserId(userObj.ID, 1, -1)
if err != nil {
return nil, err
}
marshal := string(key.Marshal())
for _, sk := range keys {
if marshal != sk.KeyStr {
pubKey, _, _, _, e := ssh.ParseAuthorizedKey([]byte(sk.KeyStr))
if e != nil || marshal != string(pubKey.Marshal()) {
continue
}
}
sk.LastUsedTime = time.Now()
_ = op.UpdateSSHPublicKey(&sk)
return nil, nil
}
return nil, errors.New("public key refused")
}
func (d *SftpDriver) AuthLogCallback(conn ssh.ConnMetadata, method string, err error) {
ip := conn.RemoteAddr().String()
if err == nil {
utils.Log.Infof("[SFTP] %s(%s) logged in via %s", conn.User(), ip, method)
} else if method != "none" {
utils.Log.Infof("[SFTP] %s(%s) tries logging in via %s but with error: %s", conn.User(), ip, method, err)
}
}
func (d *SftpDriver) GetBanner(_ ssh.ConnMetadata) string {
return setting.GetStr(conf.Announcement)
}
View on GitHub (pinned to 843d9dc814)
Solutions
- Add the client's public key (~/.ssh/id_*.pub output) under the user's SSH public keys in the AList admin panel and reconnect.
- Confirm the key belongs to the same username being used to connect (keys are scoped per user ID).
- Re-copy the stored key exactly (single line, key-type base64-comment) so ssh.ParseAuthorizedKey can parse it and the marshaled form matches.
- If the client agent offers many keys, ensure the correct one is offered (ssh -i) so a later refusal is not caused by wrong-key ordering.
Example fix
# before: client key not registered, server logs 'public key refused' ssh alist@example.com # after: register the exact public key, then connect # admin UI -> Users -> SSH Public Keys -> paste contents of: cat ~/.ssh/id_ed25519.pub ssh -i ~/.ssh/id_ed25519 alist@example.com
Defensive patterns
Strategy: validation
Validate before calling
# Before connecting, confirm the key you will offer is registered: ssh-keygen -lf ~/.ssh/id_ed25519.pub # fingerprint of client key # compare with the fingerprint shown for the stored key in the AList admin panel
Prevention
- Register every client public key under the exact connecting username.
- Store keys as single-line OpenSSH format (type base64 comment).
- Use ssh -i to pin the offered key when the agent holds many keys.
When it happens
Trigger: Client offers an SSH key that is not registered for the account; the stored KeyStr is in a different format/comment so string comparison fails AND ssh.ParseAuthorizedKey fails or the re-marshaled bytes differ; all user keys were deleted from the admin panel.
Common situations: New machine / new SSH keypair not added in the AList SSH public keys settings; key was re-saved with a trailing comment or whitespace so neither raw-string nor parsed comparison matches; user uploaded a private key instead of the public key; key registered under a different user account.
Related errors
- only guest is allowed to login without authorization
- user is not allowed to access via SFTP
- oss: chunkNum invalid
- clientID and clientSecret are required in client_credentials
- share_ids is required
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/e6aca2f600121c02.
Report an issue: GitHub.