sshd "PAM 2 more authentication failures" / "ignoring max retries"
Published
pam_unix's end-of-connection tally of repeated password failures — the number printed is one less than the failures it counted, and the companion line fires when that count passes the module's compiled-in limit of 3.
What it looks like
Oct 18 03:51:11 web1 sshd-session[48211]: PAM 1 more authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=203.0.113.7 user=root
- 1Time — When it was logged; this format has no year or time zone
- 2Host — The server’s host name
- 3Program — sshd-session, one process per connection, and its process ID: a connection’s lines share it
- 4Source address — rhost: the remote host the attempt came from
- 5User — The account name
Example lines as /var/log/auth.log shows them (/var/log/secure on RHEL and Fedora):
Oct 18 03:51:11 web1 sshd-session[48211]: PAM 1 more authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=203.0.113.7 user=root Oct 18 03:52:44 web1 sshd-session[48230]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=198.51.100.22 user=deploy Oct 18 03:52:44 web1 sshd-session[48230]: PAM service(sshd) ignoring max retries; 6 > 3
On our own server, the 30 days to 25 October 2026
… more authentication failure…; logname=… uid=… euid=… tty=… ruser=… rhost=…
2,142
lines · about 71 a day · 25 source addresses
Last seen 6 October 2026
None since the server went key-only on 6 October 2026 — turning off password authentication removed this line entirely.
service(…) ignoring max retries; … > …
1,661
lines · about 55 a day
Last seen 6 October 2026
None since the server went key-only on 6 October 2026 — turning off password authentication removed this line entirely.
LogTriage's production API server (Hetzner, Germany): port 22 open to the internet, key-only since 6 October 2026 (password and keyboard-interactive authentication off); nginx in front of the API on ports 80 and 443. Counted weekly from the sshd journal; no address ever leaves the server. More in the monthly attack report; which free blocklists already list these attackers is measured in the IP blocklist report, and you can check the addresses in your own log.
Where the line comes from
Format strings as written in the source of Linux-PAM 1.7.0 — the versions this server runs. Each links to the exact line.
… more authentication failure…; logname=… uid=… euid=… tty=… ruser=… rhost=…
-
%d more authentication failure%s; logname=%s uid=%d euid=%d tty=%s ruser=%s rhost=%s %s%smessage · modules/pam_unix/support.c:311 (Linux-PAM) -
#define _PAM_SYSTEM_LOG_PREFIX "PAM"prefix when no module is named · libpam/pam_private.h:284 (Linux-PAM)
service(…) ignoring max retries; … > …
-
service(%s) ignoring max retries; %d > %dmessage · modules/pam_unix/support.c:326 (Linux-PAM) -
#define UNIX_MAX_RETRIES 3the limit it compares against · modules/pam_unix/support.c:267 (Linux-PAM)
What it means
pam_unix keeps one small record per PAM handle to track failed authentications. The source comments its fields plainly: user is the “user that’s failed to be authenticated”, name is the “attempt from user with name”, uid the “uid of calling user”, euid the “euid of calling process” and count the “number of failures so far”.
Both of these lines come from the cleanup routine for that record, not from the moment a password is rejected. When the record is released or replaced — for sshd, as the authentication phase of that connection ends — and the count is greater than 1, pam_unix logs the summary. The logging block is guarded (if (!quiet && !err)), so a silent cleanup produces nothing at all.
Two details decide how you read the number:
- It prints
count - 1. “5 more authentication failures” means pam_unix counted six. Add one. - Singular at exactly two. The plural suffix is
""when the count is 2 and"s"otherwise, which is why you see bothfailureandfailuresin the same log.
The rest of the line is the format string filled in: logname= (the record’s name field), uid=/euid= (the sshd process calling PAM), tty=, ruser=, rhost= (the client address — the field that matters) and, only when the failed account name is non-empty, a literal user= plus the name. That literal carries its own leading space on top of the one already after rhost=%s, which is why real lines show two spaces before user=. Write your regexes accordingly.
The second line follows immediately, from the same block and the same PID, when the count exceeds UNIX_MAX_RETRIES — a constant defined in the module as 3. It prints the PAM service (sshd, or **unknown** if the item is unset), the count, and that limit: ignoring max retries; 6 > 3. The wording is literal. pam_unix logs and takes no action; the limit that actually cuts a connection off is sshd’s MaxAuthTries, documented default 6, which also notes that “Once the number of failures reaches half this value, additional failures are logged.”
Neither line can appear unless PAM password or keyboard-interactive authentication actually runs. A key-only server produces none of them.
Is it an attack?
| Pattern | Reading |
|---|---|
”1 more authentication failure” for a staff account from a known address, then Accepted | Someone mistyped and retried |
One rhost=, many different user= values | Guessing across accounts — check the Invalid user and user-unknown lines on the same PIDs |
One rhost=, same user=, repeating over hours | Targeted brute force against an account that exists |
ignoring max retries on nearly every connection from a source | A client spending every attempt sshd allows — automated, not a human |
user=root | Only possible where root password login is permitted; PermitRootLogin defaults to prohibit-password, which disables password and keyboard-interactive authentication for root |
Any Accepted line from the same rhost= | Stop triaging and investigate the session |
The count is bounded by what sshd permits per connection, so a high number tells you the limit is generous, not that the attacker is close to succeeding. The account name does the real work: a real service or staff account under repeated attempts outranks a thousand failures against invented names.
How to investigate
Pivot on rhost=, on user=, and on the PID that ties one connection together.
# Last 24 hours (Debian/Ubuntu unit is ssh; RHEL/Fedora use -u sshd)
sudo journalctl -u ssh --since "24 hours ago" \
| grep -E "PAM [0-9]+ more authentication failures?;|ignoring max retries"
# Busiest sources (/var/log/auth.log; on RHEL/Fedora /var/log/secure)
sudo grep -oP 'PAM \d+ more authentication failures?;.*rhost=\K\S+' \
/var/log/auth.log | sort | uniq -c | sort -rn | head -20
# Accounts those connections were working on
sudo grep -oP 'PAM \d+ more authentication failures?;.*user=\K\S+' \
/var/log/auth.log | sort | uniq -c | sort -rn | head -20
# Connections that went past pam_unix's compiled-in limit of 3
sudo grep -c 'ignoring max retries' /var/log/auth.log
# One connection in full, by PID
sudo grep 'sshd-session\[48230\]' /var/log/auth.log
# Did anything from those sources actually get in?
sudo grep -E "Accepted (password|publickey)" /var/log/auth.log | tail -50
Check the names from the third command against /etc/passwd. For an exported auth.log the browser log analyzer groups these by source, and the SSH brute-force rule encodes the one-source-many-accounts shape as a detection.
How to stop it
- Turn off password paths and these lines disappear.
PasswordAuthentication no(defaultyes) and, where PAM is enabled,KbdInteractiveAuthentication no(defaultyes) — the manual notes that “Because PAM keyboard-interactive authentication usually serves an equivalent role to password authentication, you should disable either PasswordAuthentication or KbdInteractiveAuthentication.” With neither running, pam_unix never counts a failure. - Lower
MaxAuthTries(default 6) to cap how high the count can climb on a single connection. - Leave
PerSourcePenaltiesenabled — penalties are on by default, and a client that disconnects after one or more unsuccessful authentication attempts is refused for 5 seconds by default, accumulating to a maximum of 10 minutes once 15 seconds of penalty have accrued. - Restrict who may log in with
AllowUsers; by default login is allowed for all users, and patterns may take theUSER@HOSTform with CIDR host criteria. - Keep
LoginGraceTime(default 120 seconds) tight, and do not expose port 22 to the whole internet if a firewall rule, VPN or bastion will do.
sudo sshd -t && sudo systemctl reload ssh
Validate before reloading, and keep a working session open until you have tested a new one.
Lines you will see next to it
- authentication failure; logname=… uid=… euid=… tty=… ruser=… rhost=… PAM's pam_unix module rejected the credentials sshd asked it to check — the line names the client address in rhost= and, when it has one, the account in user=.
- … for … from … port … ssh2… sshd rejected a password authentication attempt — the line names the account that was tried, the client address and the client's source port, and marks names that are not usable accounts on this host with "invalid user".
- password check failed for user (…) PAM's password helper checked the password offered for the named account and it did not pass — a wrong password, or a name it could not resolve — and the line itself carries no address, so the sshd lines beside it are what tell you where it came from.
- Invalid user … from … port … sshd rejected the login because the name the client asked for is not a valid account on this host, so no password or key was ever checked against a real user.
- maximum authentication attempts exceeded for … from … port … ssh2 One SSH connection used up every authentication attempt sshd allows it — the MaxAuthTries limit, 6 by default — so sshd logged the account name, source address and port and tore the connection down.
Detect it
Frequently Asked Questions
- Why does the line say "2 more authentication failures" when I count three failed passwords?
- Because the module prints `failure->count - 1`, not the count itself. Add one to the number in the line to get how many failures pam_unix recorded for that PAM handle. The suffix is also computed from the count — it is singular ("1 more authentication failure") only when the count is exactly 2.
- Why is the prefix "PAM" instead of "pam_unix(sshd:auth)"?
- Both lines are written from the cleanup routine for pam_unix's failure record, outside the module stack, so libpam has no module name to print and falls back to its system log prefix, defined in libpam/pam_private.h as `_PAM_SYSTEM_LOG_PREFIX "PAM"`. The per-attempt failure lines, logged from inside the module, keep the `pam_unix(sshd:auth):` form.
- Does "ignoring max retries; 6 > 3" mean a retry limit was misconfigured or bypassed?
- No. 3 is `UNIX_MAX_RETRIES`, a constant compiled into pam_unix, and the code does nothing but log when the failure count exceeds it — the module itself does not stop the application. The per-connection limit that is actually enforced for SSH is sshd's `MaxAuthTries`, whose documented default is 6.
- Why are logname= and ruser= empty in every line?
- They are printed from the failure record's name field and the PAM_RUSER item, which are simply not populated for a network SSH login; `uid=0 euid=0` is the sshd process calling PAM as root, and `tty=ssh` is the PAM_TTY item sshd sets. The fields worth reading are `rhost=` and `user=`.
Run your own auth.log through it
Paste or drop /var/log/auth.log (or journalctl -u ssh output) into the free browser analyzer: brute force, password spraying, a successful login after failures and invalid-user sweeps are flagged with the evidence lines. Nothing is uploaded.