SQL Server "Login failed for user" (error 18456): the state tells you why
Fix SQL Server error 18456 "Login failed for user": find the real reason in the log by its state, then fix the password, mixed mode, a disabled login or the database.
by OhSudo ·
Checked on real software: SQL Server 2022 · November 2026How we check
Not sure this is your cause?Find it step by step: Can't connect to the database →
Login failed for user 'app'. (Microsoft SQL Server, Error: 18456)The good news is in that message: you reached the server. The network, the port and the instance name all work. The server just refused this login, and it won’t tell the client why, so that attackers can’t learn from it.
It tells its own log, though. The real reason is a number called the state.
TL;DR
Find the state in the SQL Server error log:
Error: 18456, Severity: 14, State: 8.Login failed for user 'app'. Reason: Password did not match that for the login provided. [CLIENT: 10.0.0.5]Then look up the state in the table below. Modern versions also write the reason in plain words on the next line.
1. Read the log
If you can log in with another account, use the query above, or in SSMS go to Management → SQL Server Logs.
If you can’t log in at all, the log is a plain text file:
C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Log\ERRORLOG # Windows (16 = SQL Server 2022)/var/opt/mssql/log/errorlog # LinuxIn a container:
docker logs mssql 2>&1 | grep -A1 18456Ignore the state in the client’s error details: it’s usually 1, which only means “details withheld”.
2. What the state means
| State | Means | Go to |
|---|---|---|
| 2, 5 | The login doesn’t exist | Section 3 |
| 6 | A Windows login name was typed with SQL Server authentication | Section 4 |
| 7 | The login is disabled, and the password was wrong too | Section 5 |
| 8, 9 | Wrong password | Section 3 |
| 11, 12 | The login is valid, but has no access to the server | Section 6 |
| 38, 40 | The login is fine, but it can’t open its database | Section 7 |
| 58 | The server only allows Windows authentication | Section 4 |
3. Wrong password, or no such login
Check that the login exists, and whether it’s enabled, as an administrator:
SELECT name, type_desc, is_disabled, default_database_nameFROM sys.server_principalsWHERE name = 'app';No row means there’s no such login. Create it, then give it access to its database:
CREATE LOGIN app WITH PASSWORD = 'new-password-here';USE shop;CREATE USER app FOR LOGIN app;ALTER ROLE db_datareader ADD MEMBER app;ALTER ROLE db_datawriter ADD MEMBER app;Otherwise set a new password:
SQL Server can enforce the Windows password policy, so a weak password fails with a different error. The Password Generator gives you one that passes, and with shell-safe symbols it won’t break a connection string either.
A login with MUST_CHANGE set fails with its own error, 18488: The password of the account must be changed. An application can’t answer that prompt, so set the password yourself, as above.
4. Windows and SQL logins are different things
State 58: the server is in Windows authentication mode. SQL logins, including sa, are refused until you allow them. In SSMS: right-click the server → Properties → Security → SQL Server and Windows Authentication mode. Or with T-SQL:
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', REG_DWORD, 2;Either way, restart the service for it to apply:
Restart-Service MSSQLSERVER # a named instance: 'MSSQL$SQLEXPRESS'State 6: DOMAIN\user typed into the SQL login box. A Windows account doesn’t use a password here. Choose Windows Authentication in SSMS, or in a connection string use Integrated Security=true instead of a user and password.
5. A disabled login
sa is the usual case: it’s disabled by default if you installed with Windows authentication only.
A locked-out login (too many wrong passwords under the policy) is unlocked the same way:
For applications, prefer a login of their own over sa.
6. A valid login without access
Your Windows account is known, but has no way in. This is often a Windows group that was removed, or an admin who isn’t running SSMS elevated, since User Account Control hides the Administrators group until you do. Right-click SSMS → Run as administrator, or add the account directly:
7. The login is fine, but the database isn’t
States 38 and 40 mean the login worked, and opening the database didn’t: it was renamed, dropped or is offline, or the login has no user in it. The log names the database:
Reason: Failed to open the explicitly specified database 'shop'.Check the database, then check the mapping:
If it’s the login’s default database that’s gone, connect by naming another one (in SSMS: Options → Connection Properties → Connect to database, or sqlcmd -d master), then fix it:
After restoring a database on another server, its users may have lost their logins. ALTER USER app WITH LOGIN = app; reconnects them.
8. Locked out completely
No administrator can log in? On Windows, a local administrator can get in through single-user mode:
net stop MSSQLSERVERnet start MSSQLSERVER /m"SQLCMD"sqlcmd -S . -E -Q "CREATE LOGIN [CONTOSO\alex] FROM WINDOWS; ALTER SERVER ROLE sysadmin ADD MEMBER [CONTOSO\alex];"net stop MSSQLSERVERnet start MSSQLSERVEROn Linux, sudo systemctl stop mssql-server, then sudo /opt/mssql/bin/mssql-conf set-sa-password, and start it again.
Warning
Don’t publish port 1433 to the internet, and don’t leave sa enabled with a weak password. A stream of 18456 errors from unknown addresses in your log usually means someone is already guessing. The Port Lookup has an entry for 1433.
Shell, we have a problem!
Similar, but different: A network-related or instance-specific error means you never reached the server: see SQL Server error 40 and 26. The SELECT permission was denied means you logged in, without rights to that object. Cannot open database requested by the login is about the database: see error 4060. And for the same kind of error on other engines, see MySQL error 1045 and PostgreSQL “password authentication failed”. If you can log in and writes fail, see The transaction log is full. Once logged in, IDENTITY_INSERT is set to OFF is a common first error when copying data between tables. Before the login, a client can stop at The certificate chain was issued by an authority that is not trusted.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.