wavetermdev/waveterm · error · ConnectionError
no identity files remaining
Error message
no identity files remaining
What it means
The SSH public-key auth callback (createPublicKeyCallback signer iterator) returns this ConnectionError once it has exhausted both ssh-agent signers (auth sock) and configured identity key files. golang.org/x/crypto/ssh keeps invoking the callback for each offered auth method, so this error signals 'no more keys to try' rather than a single key failure. It surfaces when every candidate key has been consumed and the server still requests public-key auth.
Source
Thrown at pkg/remote/sshclient.go:317
authSockSigners = append(authSockSigners, authSockSignersExt...)
authSockSignersPtr := &authSockSigners
return func() (outSigner []ssh.Signer, outErr error) {
defer func() {
panicErr := panichandler.PanicHandler("sshclient:publickey-callback", recover())
if panicErr != nil {
outErr = panicErr
}
}()
// try auth sock
if len(*authSockSignersPtr) != 0 {
authSockSigner := (*authSockSignersPtr)[0]
*authSockSignersPtr = (*authSockSignersPtr)[1:]
return []ssh.Signer{authSockSigner}, nil
}
if len(*identityFilesPtr) == 0 {
return nil, ConnectionError{ConnectionDebugInfo: debugInfo, Err: fmt.Errorf("no identity files remaining")}
}
identityFile := (*identityFilesPtr)[0]
blocklogger.Infof(connCtx, "[conndebug] trying keyfile %q...\n", identityFile)
*identityFilesPtr = (*identityFilesPtr)[1:]
privateKey, ok := existingKeys[identityFile]
if !ok {
log.Printf("error with existingKeys, this should never happen")
// skip this key and try with the next
return createDummySigner()
}
unencryptedPrivateKey, err := ssh.ParseRawPrivateKey(privateKey)
if err == nil {
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
if err == nil {
if utilfn.SafeDeref(sshKeywords.SshAddKeysToAgent) && agentClient != nil {
agentClient.Add(agent.AddedKey{
PrivateKey: unencryptedPrivateKey,View on GitHub (pinned to a4447c1563)
Solutions
- Verify the remote's ~/.ssh/authorized_keys contains the public key corresponding to your private key.
- Confirm SshIdentityFile points to a readable, valid private key (check [conndebug] log line 'trying keyfile').
- Start ssh-agent and add your key (ssh-add), or use an agent so signers are available.
- Enable password or keyboard-interactive auth so another method can succeed after keys are exhausted.
- If the key is passphrase-protected, make sure the passphrase prompt isn't disabled by SshBatchMode.
Example fix
// before (config)
connection: { "sshidentityfile": ["~/.ssh/nonexistent_key"] }
// after
connection: { "sshidentityfile": ["~/.ssh/id_ed25519"] } // readable key whose pubkey is on the server Defensive patterns
Strategy: fallback
Validate before calling
// before connecting, check the key exists and is readable
if _, err := os.Stat(identityFile); err != nil {
return fmt.Errorf("identity file %s missing/unreadable: %w", identityFile, err)
} Try / catch
var ce ConnectionError
if err := Connect(...); err != nil {
if errors.As(err, &ce) && strings.Contains(ce.Error(), "no identity files remaining") {
// fall back to password / keyboard-interactive auth or fix key config
}
} Prevention
- Ensure at least one valid identity file is configured and readable.
- Run ssh-agent with keys loaded so the auth-sock path has signers.
- Verify the public key is installed in the remote's authorized_keys.
- Leave password/kbd-interactive auth enabled as a secondary method.
- Read the [conndebug] logs to see which keyfiles were attempted.
When it happens
Trigger: SSH connection where all auth-sock signers were offered and the last configured identity file was consumed; the server continues asking for public-key auth (key rejected/not authorized), so the callback has nothing left to return.
Common situations: Public key not in the remote's authorized_keys; wrong SshIdentityFile configured; key file unreadable (permissions) so it was skipped during preload leaving an empty list; no ssh-agent running and no keys present.
Related errors
- ai:apitoken is required
- cannot parse connection name: %w
- getting ssh connection status: %w
- connecting connection: %w
- error getting jwt public key: %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/e0ad612b7c40df1e.
Report an issue: GitHub.