Skip to content
ohsudo, Home
Databases

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.

Beginner5 min readApplies to SQL Server 2017+ · SQL Server Express · Windows Server · SQL Server on Linux · SSMS · sqlcmd

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:

EXEC xp_readerrorlog 0, 1, N'Login failed';
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 # Linux

In a container:

Terminal window
docker logs mssql 2>&1 | grep -A1 18456

Ignore 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_name
FROM sys.server_principals
WHERE 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:

ALTER LOGIN app WITH PASSWORD = 'new-password-here';

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:

Terminal window
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.

ALTER LOGIN sa WITH PASSWORD = 'new-password-here';
ALTER LOGIN sa ENABLE;

A locked-out login (too many wrong passwords under the policy) is unlocked the same way:

ALTER LOGIN app WITH PASSWORD = 'new-password-here' UNLOCK;

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:

CREATE LOGIN [CONTOSO\alex] FROM WINDOWS;

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:

SELECT name, state_desc FROM sys.databases;
USE shop;
CREATE USER app FOR LOGIN app;

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:

ALTER LOGIN app WITH DEFAULT_DATABASE = master;

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:

Terminal window
net stop MSSQLSERVER
net start MSSQLSERVER /m"SQLCMD"
sqlcmd -S . -E -Q "CREATE LOGIN [CONTOSO\alex] FROM WINDOWS; ALTER SERVER ROLE sysadmin ADD MEMBER [CONTOSO\alex];"
net stop MSSQLSERVER
net start MSSQLSERVER

On 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.

Tools

Try it yourself

Articles

Related articles