sshd "Disconnected from authenticating/invalid user …": What It Means
Published
The client told sshd which account it wanted and then ended the connection before authentication succeeded, so the line names that account along with the source address and port.
What it looks like
Oct 18 03:51:11 web1 sshd-session[48211]: Disconnected from invalid user admin 203.0.113.7 port 54122 [preauth]
- 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
- 4User — The account name
- 5Source address — The client’s IP address
- 6Source port — The client’s source port; with the address it identifies one connection
- 7[preauth] — Logged before the user authenticated
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]: Disconnected from invalid user admin 203.0.113.7 port 54122 [preauth] Oct 18 03:51:44 web1 sshd-session[48230]: Disconnected from authenticating user root 198.51.100.22 port 40118 [preauth] Oct 18 04:07:02 web1 sshd-session[48502]: Disconnected from authenticating user deploy 192.0.2.44 port 51902 [preauth]
On our own server, the 30 days to 25 October 2026
Disconnected from …
26,063
lines · about 869 a day · 1,246 source addresses
Last seen 25 October 2026
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 OpenSSH 10.2p1 — the versions this server runs. Each links to the exact line.
-
Disconnected from %smessage · packet.c:2031 (OpenSSH) -
%.200s%s%s port %dconnection id: preamble, address, port · packet.c:2004 (OpenSSH) -
authctxt->valid ? "authenticating " : "invalid ", user);preamble: authenticating or invalid user · auth2.c:312 (OpenSSH) -
%suser %spreamble format · auth2.c:311 (OpenSSH) -
mon_dispatch == mon_dispatch_postauth20 ? "postauth" : "preauth");the [preauth] tag on lines from the pre-authentication process · monitor.c:481 (OpenSSH)
What it means
Disconnected from … comes from sshd’s connection-terminating error handler in packet.c. Three branches sit next to each other there: one logs Connection closed by %s, one logs Connection reset by %s when a system call fails with errno == ECONNRESET, and this one logs Disconnected from %s for the SSH_ERR_DISCONNECTED case. The handler logs and exits — the connection is finished either way.
The %s is a connection identifier built as %.200s%s%s port %d: an optional logging preamble, the client’s IP address, and the client’s source port for that one TCP connection. The port is what lets you tie this line to the other lines sharing the same PID.
Every line matching this page’s pattern carries the preamble, so every one of them names an account. sshd installs the preamble while handling the client’s first authentication request, writing authenticating user <name> when the account lookup produced a usable record and invalid user <name> when it did not — in that case the code substitutes fake password information, the same decision described on the Invalid user page. That happens before any password or key is evaluated, so the line says only which account the client asked for, never that a credential was tried or accepted.
[preauth] is appended by sshd’s monitor to messages relayed from the pre-authentication process. Its presence means the connection never reached an authenticated session.
Is it an attack?
| Pattern | Reading |
|---|---|
invalid user <random name>, one or two per source | Scanner working through a stock name list — noise |
invalid user …, many different names from one source in minutes | Name guessing or spraying; correlate with Invalid user lines on the same PIDs |
authenticating user <real account>, no password failures nearby | A client that asked for a real account and gave up when its method was refused |
authenticating user <real account> right after Failed password lines | Brute force against an account that exists — higher priority |
Same source producing these and then an Accepted line | Stop triaging and investigate the session |
| One internal host, one account, repeating on a schedule | Usually a misconfigured automation client, not an attack |
The line is the ending of a story told by the lines before it on the same PID, so always read the connection as a whole rather than the disconnect alone.
How to investigate
Pivot on the account name, the source address and the PID.
# Last 24 hours from the journal (Debian/Ubuntu unit is ssh; RHEL/Fedora use -u sshd)
sudo journalctl -u ssh --since "24 hours ago" | grep "Disconnected from"
# Which accounts clients named before disconnecting (/var/log/auth.log; RHEL/Fedora /var/log/secure)
sudo grep -oP 'Disconnected from (?:authenticating|invalid) user \K\S+' \
/var/log/auth.log | sort | uniq -c | sort -rn | head -20
# Busiest source addresses
sudo grep -oP 'Disconnected from (?:authenticating|invalid) user \S+ \K\S+' \
/var/log/auth.log | sort | uniq -c | sort -rn | head -20
# Only the valid-account ones — these name accounts sshd was willing to try
sudo grep 'Disconnected from authenticating user' /var/log/auth.log | tail -40
# The full story of one connection, by PID
sudo grep 'sshd-session\[48230\]' /var/log/auth.log
# Did any of these sources actually get in?
sudo grep -E 'Accepted (password|publickey)' /var/log/auth.log | tail -50
Check the names from the second command against /etc/passwd: an authenticating user preamble for a real service or staff account is worth more of your time than a thousand invalid user disconnects. For an exported auth.log, the browser log analyzer groups these lines by source, and the SSH brute-force rule encodes the one-source-many-names pattern as a detection.
How to stop it
A remote client can always hang up, so aim for fewer unwanted connections and nothing worth guessing.
- Keep port 22 off the open internet where you can — firewall it to known ranges, or put it behind a VPN or bastion. Nothing else reduces the volume as much.
- Leave
PerSourcePenaltiesenabled. The manual says penalties are on by default: a client that disconnects after one or more unsuccessful authentication attempts is refused for 5 seconds by default, accumulating up to a maximum of 10 minutes, with a minimum of 15 seconds accrued before enforcement begins. Thenoauthpenalty (default 1s) covers clients that disconnect without attempting authentication, and the manual warns to use it cautiously as it may penalise legitimate scanning tools such asssh-keyscan(1). - Remove passwords from the equation with
PasswordAuthentication no(the default isyes) and, where PAM is enabled,KbdInteractiveAuthentication no— the manual notes PAM keyboard-interactive authentication usually serves an equivalent role to password authentication. - Keep
MaxAuthTries(default 6) andLoginGraceTime(default 120 seconds) tight, so a connection that guesses or lingers is cut off sooner. - Limit who may log in with
AllowUsers; by default login is allowed for all users, and patterns may take theUSER@HOSTform with CIDR host criteria.PermitRootLogindefaults toprohibit-password.
sudo sshd -t && sudo systemctl reload ssh
Validate the configuration before reloading, and keep an existing session open until a new one works.
Lines you will see next to it
- 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.
- … 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".
- Connection closed by … The client at the other end of the SSH connection went away — closed it cleanly, or reset it — and sshd logged the address, port and (if the client had already named an account) the user it was trying before it quit.
- Received disconnect from … port …:…: … The client told the server it was closing the connection — sshd logged the client's address and port, the numeric disconnect reason the client sent and the text that came with it.
Detect it
Frequently Asked Questions
- What is the difference between "Disconnected from" and "Connection closed by"?
- They are two branches of the same connection-terminating error handler in sshd's packet layer. "Connection closed by" is logged for the SSH_ERR_CONN_CLOSED case, "Connection reset by" when a system call fails with ECONNRESET, and "Disconnected from" for the SSH_ERR_DISCONNECTED case — the disconnect path rather than a bare TCP close. In logs, the "Disconnected from" line usually follows a "Received disconnect from …" line with the same PID, because the client announced it was leaving.
- Does "authenticating user deploy" mean the attacker authenticated as deploy?
- No. The preamble is set when sshd handles the client's first authentication request, using "authenticating " when the account lookup returned a usable record and "invalid " when it did not. It only tells you the name matched something sshd was prepared to try. The "[preauth]" tag on the same line says the connection ended in the pre-authentication process, so no session was ever established.
- Why do I still see these lines after turning password authentication off?
- Because the user name preamble is installed as soon as the client asks to authenticate as somebody, before any password is checked. A client that only knows how to send passwords will still name an account, be offered methods it cannot use, and disconnect — producing this line with no "Failed password" line anywhere near it.
- Should I alert on these lines?
- Not on their own — on an internet-facing host they are ordinary scanner noise. Alert on the shape instead: one source naming many different accounts within minutes, any line with an "authenticating user" preamble for a real staff or service account, and above all an "Accepted" line from a source that had been producing these.
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.