- Error number
- 15151
- Severity
- 16 (user-correctable error)
- State
- 1
- Product
- Microsoft SQL Server Database Engine
- Versions
- All supported SQL Server versions (2016 to 2025), Azure SQL Database, Azure SQL Managed Instance
- Category
- Logins & Permissions
- Last reviewed
- 24 October 2026
On this page
What it means
Error 15151 means a security statement named a user, login, role or schema that SQL Server cannot see: either it does not exist in this scope, or you lack the permission that would let you see and change it.
The message is built from three parts: the action (drop, alter, add, find), the kind of principal (user, login, role, schema, principal) and the name in quotes. Read it as "I could not do ACTION on KIND NAME". For example, ALTER ROLE ... ADD MEMBER with a missing member says Cannot add the principal, and a GRANT to a missing user says Cannot find the user.
SQL Server deliberately gives the same answer for "does not exist" and "you may not see it", so that a user without permission cannot probe which principals exist. In our tests a user without ALTER ANY USER trying to drop an existing user got exactly the same message as a drop of a name that does not exist. Severity 16 is a user-correctable error; nothing changed.
Common causes
- The name is wrong: a typo, a missing domain prefix on a Windows user (
CONTOSO\appsvc), or brackets missing around a name with special characters. - You are in the wrong database: users, roles and schemas are per database, so the statement ran in master or another database instead of the one that holds the principal.
- Logins and users were confused:
DROP USERwas used for a server login, orDROP LOGINfor a database user. - A deployment script drops or alters a principal that an earlier run (or another script) already removed.
- The caller lacks the permission to change the principal (for example
ALTER ANY USER,ALTER ANY ROLEorALTER ANY LOGIN), so the principal is reported as not found.
Diagnose it
Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.
Am I in the right database, and who am I?
SELECT DB_NAME() AS current_database,
SUSER_SNAME() AS login_name,
USER_NAME() AS user_name; The database must be the one that holds the user, role or schema. If you are impersonating (EXECUTE AS), the names show the impersonated context.
Does a database principal or schema with a similar name exist here?
SELECT name, type_desc, 'principal' AS kind
FROM sys.database_principals
WHERE name LIKE N'%app%'
UNION ALL
SELECT name, 'SCHEMA', 'schema'
FROM sys.schemas
WHERE name LIKE N'%app%'; A row with a slightly different spelling or a domain prefix is the name to use. No row means the principal is not in this database.
Is it a server login rather than a database user?
SELECT name, type_desc, is_disabled
FROM sys.server_principals
WHERE name LIKE N'%app%'; A row here and none in the previous check means it is a login: use DROP LOGIN or ALTER LOGIN, or create a user for it in the database.
Do I have the permission to change principals here?
SELECT permission_name
FROM fn_my_permissions(NULL, 'DATABASE')
WHERE permission_name IN (N'ALTER ANY USER', N'ALTER ANY ROLE', N'ALTER ANY SCHEMA', N'CONTROL'); No rows means the error may be a permission problem even though the principal exists; ask an administrator or a member of db_securityadmin or db_owner.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Run the statement in the right database with the exact name
Client or network sideSwitch to the database that holds the principal and copy the name from sys.database_principals, including any domain prefix and brackets.
USE Sales;
DROP USER [CONTOSO\appsvc];
Make security scripts idempotent
Changes permissionsUse IF EXISTS (available for users, roles and schemas since SQL Server 2016) or check the catalog view first, so reruns do not fail.
DROP USER IF EXISTS app_user;
DROP ROLE IF EXISTS app_role;
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = N'app_user')
ALTER ROLE db_datareader ADD MEMBER app_user;
Create the missing user before adding it to a role or granting to it
Changes permissionsWhen the login exists but has no user in this database, create the user first, then add it to the role it needs.
CREATE USER app_user FOR LOGIN app_user;
ALTER ROLE db_datareader ADD MEMBER app_user;
Ask for the narrowest permission that covers the task
Changes permissionsIf the principal exists and only permission is missing, an administrator can grant, for example, ALTER ANY USER or membership of db_securityadmin to the person who manages users, rather than db_owner.
GRANT ALTER ANY USER TO [CONTOSO\dba_team];
Examples
Dropping a user that does not exist
DROP USER app_user;
Msg 15151, Level 16, State 1, Line 1 Cannot drop the user 'app_user', because it does not exist or you do not have permission.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
Adding a missing user to a role
ALTER ROLE db_datareader ADD MEMBER app_user;
Msg 15151, Level 16, State 1, Line 1 Cannot add the principal 'app_user', because it does not exist or you do not have permission.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
The user exists, but the caller has no permission
CREATE USER report_owner WITHOUT LOGIN;
CREATE USER intern WITHOUT LOGIN;
GO
EXECUTE AS USER = 'intern';
DROP USER report_owner;
REVERT;
Msg 15151, Level 16, State 1, Line 2 Cannot drop the user 'report_owner', because it does not exist or you do not have permission.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
How to prevent it
Write security changes as scripts that state the database (USE) and use IF EXISTS or catalog checks, and keep them in source control next to the schema. Store principal names exactly as SQL Server shows them, including the domain prefix for Windows users and groups.
Give the people who manage users the specific permissions they need (ALTER ANY USER, db_securityadmin) so that a 15151 really means "not found". The SQL Server security lesson explains logins, users and roles.
Common questions
How do I tell "does not exist" from "no permission"?
The message is the same on purpose. Ask someone with more rights to look for the name in sys.database_principals or sys.server_principals; if it exists there, the problem is your permission.
Why does DROP USER fail for a login I can see in Security, Logins?
Logins live at server level and users live in each database. DROP USER only looks in the current database. Use DROP LOGIN for the login, and DROP USER in each database where it has a user.
Does DROP USER IF EXISTS hide permission problems?
It can. In our test a user without permission ran DROP USER IF EXISTS against an existing user: no error, and the user was still there. Check sys.database_principals afterwards if the drop must happen.
Learn more on CodeWithSQL
Official documentation
- DROP USER (Transact-SQL)
- ALTER ROLE (Transact-SQL)
- Database engine events and errors 15000 to 15999 (Microsoft Learn)
Last technically reviewed 24 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.