Skip to main content
DevOpsintermediate

Login Failed for User - SQL Server 18456

Fix 'Login failed for user' (SQL Server, Error: 18456). The client hides the reason - read the State number in the error log and fix the actual cause.

10 min readUpdated August 2026

Login failed for user with Error: 18456 is SQL Server rejecting an authentication attempt without telling the client why:

Login failed for user 'appuser'. (Microsoft SQL Server, Error: 18456)

That is deliberate: the client is given the least informative version so an attacker cannot learn whether a login exists, is disabled, or merely had the wrong password. The real reason exists — as a State number — in the server's error log. Everything below depends on reading it.

Why This Happens

SQL Server logs two lines per failure. The first carries the state; the second carries the login and the client address:

2026-08-12 20:12:56.34  Logon  Error: 18456, Severity: 14, State: 8.
2026-08-12 20:12:56.34  Logon  Login failed for user 'appuser'. [CLIENT: 10.0.3.14]

State 8 means the password was wrong. State 5 means the login does not exist. State 38 means the database could not be found. These call for completely different fixes, and the client message is identical for all of them — which is why 18456 generates so much wasted effort.

Fix 1: Read the State Number

In SQL Server Management Studio: expand Management → SQL Server Logs, open the current log, and filter on 18456. Or query it directly, which is faster:

EXEC xp_readerrorlog 0, 1, N'18456', NULL, NULL, NULL, N'DESC';

On Linux the log is a file, typically /var/opt/mssql/log/errorlog:

sudo grep -A1 "Error: 18456" /var/opt/mssql/log/errorlog | tail -20

Now look your state up.

The State Table

StateMeaningWhat to do
1Error information is not availableYou are reading the client message, not the log. Go to the server log.
2, 5User ID is not validThe login does not exist on this instance — check spelling and which server you are pointed at
6A Windows login name was used with SQL Server AuthenticationUse a trusted connection instead
7Login is disabled and the password is incorrectBoth need attention; see the note on sa below
8The password is incorrectFix the credential; the login itself is fine
9Password is not validAs above
11, 12Login is valid but server access failedOften a Windows admin without an elevated token — try Run as administrator, or grant access explicitly
18Password must be changedChange it; a policy is forcing expiry
38, 46Could not find the database requested by the userThe login works; the database is missing, offline, or not accessible
58SQL Authentication attempted on a Windows-Authentication-only instanceUse a trusted connection, or change the server's authentication mode
62Contained-database SID mismatchRe-map the user in the contained database
122–124Empty user name or passwordThe connection string is not supplying credentials
126Database requested does not existCorrect the database name in the connection string
102–111, 132–133Microsoft Entra ID failureTroubleshoot on the identity side

Fix 2: By State

States 2 and 5 — the login does not exist

The log confirms it with Reason: Could not find a login matching the name provided. Check what actually exists:

SELECT name, type_desc, is_disabled, create_date
FROM sys.server_principals
WHERE type IN ('S','U','G')
ORDER BY name;

This is very often a connection string still pointing at a development server after a deployment. Verify the target before creating anything:

SELECT @@SERVERNAME AS server_name, @@VERSION AS version;

If the login genuinely belongs on this instance, create it with only what it needs — not a server role:

CREATE LOGIN [appuser] WITH PASSWORD = N'<strong-password>';
USE [appdb];
CREATE USER [appuser] FOR LOGIN [appuser];
ALTER ROLE db_datareader ADD MEMBER [appuser];
ALTER ROLE db_datawriter ADD MEMBER [appuser];

Grant db_owner or sysadmin only when the application genuinely performs schema changes — those memberships are how a single leaked application credential turns into a full server compromise.

Advertisement

State 8 — the password is wrong

The log says Reason: Password did not match that for the login provided. Nothing is wrong with the server — fix the credential where it lives. Check for a trailing space, an unescaped character in a config file, or a rotated password that reached one deployment target but not another.

If the password must be reset:

ALTER LOGIN [appuser] WITH PASSWORD = N'<new-strong-password>';

State 7 — disabled login

The account exists but is disabled. This is the state you get when someone tries sa on an instance where it is correctly turned off. Leave sa disabled — it is a universally known superuser name and the first thing credential-stuffing tools try. Create a named login for the job instead. If a legitimate application login was disabled by mistake:

ALTER LOGIN [appuser] ENABLE;

States 11 and 12 — valid login, server access failed

For a Windows account that is an administrator only through group membership, the client may be running without an elevated token — launch it with Run as administrator. The durable fix is to grant the account access explicitly so the permission survives changes to that group. The log may also show Token-based server access validation failed with an infrastructure error, which points at Kerberos, SPNs, or a DENY on a group the user belongs to.

States 38, 46 and 126 — the database is the problem

Authentication succeeded; the database did not. The log names it:

Login failed for user 'appuser'. Reason: Failed to open the database 'appdb' specified in the login properties

Check the database is present and online:

SELECT name, state_desc, user_access_desc
FROM sys.databases
ORDER BY name;

Anything other than ONLINE is a database availability problem, not a login one. If the database is fine but the login has no user in it, map one with CREATE USER [appuser] FOR LOGIN [appuser];.

If the login's default database is unavailable you may also see Cannot open user default database. Login failed. with Error: 4064. Point the login at an available default, or name a database explicitly in the connection string:

ALTER LOGIN [appuser] WITH DEFAULT_DATABASE = [appdb];

States 6 and 58 — wrong authentication mode

State 58 means a SQL login was offered to an instance accepting only Windows Authentication. The log spells it out: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only.

The lower-impact fix is a trusted connection — add Integrated Security=SSPI (or Trusted_Connection=Yes for ODBC) to the connection string.

Changing the server's authentication mode requires restarting the SQL Server service, which disconnects every session and takes the instance down until it comes back. That is a maintenance window, not a quick toggle. Only do it if the application genuinely cannot use Windows Authentication, and schedule it.

Verify the Fix

Test as the actual identity against the actual database, not as yourself:

SELECT SUSER_NAME()   AS login_name,
       USER_NAME()    AS database_user,
       DB_NAME()      AS current_database,
       IS_SRVROLEMEMBER('sysadmin') AS is_sysadmin;

is_sysadmin should be 0 for an application login. From the command line:

sqlcmd -S sqlhost -U appuser -d appdb -Q "SELECT SUSER_NAME(), DB_NAME();"

Then re-read the error log and confirm no new 18456 entries appear for that login.

Prevent It Coming Back

  • Give every application its own named login with database-scoped roles, so a failure names the application and a leak is contained.
  • Keep sa disabled and renamed where policy allows.
  • Alert on repeated 18456 entries. A burst of State 5 or State 8 from one address is a credential-stuffing attempt, not a configuration problem — the [CLIENT: <ip>] field is what makes that visible.
  • Store connection strings in a secret manager so a rotated password reaches every deployment target at once.
  • Set an explicit default database on each login so a database going offline does not break logins that never used it.

Next Steps

Frequently Asked Questions

Find answers to common questions

A connection attempt was rejected during authentication. SQL Server deliberately hides the reason from the client so an attacker cannot learn whether a login exists or which part of the credentials was wrong. The actual reason is recorded as a State number in the SQL Server error log.

State 1 means error information is not available to you. SQL Server returns it to every unauthenticated client on purpose. The real state — 5, 8, 38 and so on — is written only to the server's error log, which is why you cannot diagnose 18456 from the client alone.

In the SQL Server error log. Open Management Studio, expand Management then SQL Server Logs, and read the current log; or query xp_readerrorlog. Look for a line reading 'Error: 18456, Severity: 14, State: N.' immediately followed by the Login failed line with the client IP.

The password did not match the login provided. The login exists and is enabled, and only the password is wrong. Fix the credential in the connection string or have an administrator reset the password — do not start changing server settings for this state.

The user ID is not valid — SQL Server could not find a login with that name. It is usually a typo, a connection string still pointing at a development server, or a login that was never created on this instance. The error log also records 'Could not find a login matching the name provided'.

The database requested by the user could not be found. The login authenticated successfully but its default database, or the database named in the connection string, is missing, offline, or inaccessible to it. The log names the database in a 'Failed to open the database' message.

A client attempted SQL Server Authentication while the instance is configured for Windows Authentication only. Either connect with a trusted connection, or have an administrator switch the instance to mixed mode — which requires a service restart and therefore a maintenance window.

The login is valid but server access failed. A common cause is a Windows user who has access only through the local administrators group without an elevated token, so launching the client with Run as administrator resolves it. Otherwise the login needs to be granted access explicitly.

They are usually not the same identity or the same target. SSMS may use your Windows account while the application uses a SQL login or a service account, and the application may name a different database or instance. Compare the states logged for each attempt — they are frequently different.

No. The sa account is a well-known superuser target and should stay disabled. Create a named login with only the permissions the application needs and map it to the specific database. If sa is disabled you will see State 7, which tells you the account is disabled rather than that you should re-enable it.