Download

Cannot find the user because it does not exist or you do not have permission

The statement names a user, login, role or schema that SQL Server can’t find, or one you lack the permission to change, and the message deliberately doesn’t say which. Most often you granted to a login’s name in a database where that login has no user yet: create the user first.

SQL Server error 15151· Tested on SQL Server 2022 RTM-CU27 (16.0.4295.3), and a temporary 2022 server for logins; same messages on 2019 RTM-CU32-GDR and 2025 RTM-CU9· Updated 11 October 2026

Cannot find the user 'seo_err_nobody', because it does not exist or you do not have permission.

What it means

A security statement named a principal (a user, login or role) or a schema that SQL Server couldn’t act on. Either it doesn’t exist where SQL Server looked, or you don’t have the permission to see or change it. The message doesn’t say which, so that it can’t be used to discover names you aren’t allowed to see:

Msg 15151, Level 16, State 1, Server 7732422b7f56, Line 1
Cannot find the user 'seo_err_nobody', because it does not exist or you do not have permission.

The verb depends on the statement: Cannot find the user (GRANT … TO), Cannot add the principal (ALTER ROLE … ADD MEMBER), Cannot alter the login (ALTER LOGIN), Cannot drop the user, the login, the role or the schema (DROP …).

Logins and users are different things. A login lets you sign in to the server; a user lives inside one database and is mapped to a login. GRANT, DENY, ALTER ROLE and DROP USER look for users in the current database; ALTER LOGIN and DROP LOGIN look for logins on the server.

Common causes

  1. Granting to a login that has no user in this database. The login app exists, but nobody ran CREATE USER app in this database, so GRANT SELECT … TO app can’t find a user called app.
  2. The wrong database. Users are per database; the script ran in master or another default.
  3. The user has another name than the login, say app_user for the login app.
  4. No permission over logins. ALTER LOGIN and DROP LOGIN need ALTER ANY LOGIN (the securityadmin role) or CONTROL SERVER. A login without them gets Cannot alter the login 'sa'… when trying to enable or reset sa, even though sa exists.
  5. Already dropped: a cleanup script run twice.

CREATE USER … FOR LOGIN with a login that doesn’t exist (or that you can’t see) is error 15007: '<name>' is not a valid login or you do not have permission.

How to fix it

Check what exists, where you are

SELECT DB_NAME() AS current_database;

SELECT dp.name AS user_name, dp.type_desc, sp.name AS login_name
FROM sys.database_principals AS dp
LEFT JOIN sys.server_principals AS sp ON sp.sid = dp.sid
WHERE dp.type IN ('S', 'U', 'G', 'E', 'X', 'R')
ORDER BY dp.name;

The second query lists the database’s users and roles with the login each user belongs to. Without VIEW ANY DEFINITION or a similar permission, sys.server_principals shows you only your own login, sa and the server roles, so a missing row there doesn’t prove a login doesn’t exist.

Create the user, then grant

USE sales;
CREATE USER [app] FOR LOGIN [app];
ALTER ROLE db_datareader ADD MEMBER [app];
GRANT EXECUTE ON SCHEMA::dbo TO [app];

This needs ALTER ANY USER in the database (db_owner or db_accessadmin). If the user already exists but belongs to no login (after a restore from another server), CREATE USER fails with 15023; re-map it with ALTER USER [app] WITH LOGIN = [app] instead, as described under error 916.

Ask for login permissions, or have an administrator run it

Changing logins (passwords, enabling sa, dropping) is for members of securityadmin or sysadmin. On Azure SQL Database, logins are managed in the master database by the server admin.

Make cleanup scripts safe to re-run

DROP USER IF EXISTS [app];
DROP ROLE IF EXISTS [reporting];
DROP SCHEMA IF EXISTS [staging];

These need SQL Server 2016 or later. DROP LOGIN has no IF EXISTS; check SUSER_ID(N'app') IS NOT NULL first.

Reproduce it

On SQL Server 2022 (16.0.4295.3) with sqlcmd, in database inlet, as a database owner, each statement in its own batch:

GRANT SELECT ON SCHEMA::seo_err_mssql TO seo_err_nobody;
ALTER ROLE db_datareader ADD MEMBER seo_err_nobody;
DROP USER seo_err_nobody;
DROP SCHEMA seo_err_noschema;
CREATE USER seo_err_user2 FOR LOGIN seo_err_nologin;
Msg 15151, Level 16, State 1, Server 7732422b7f56, Line 1
Cannot find the user 'seo_err_nobody', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 7732422b7f56, Line 1
Cannot add the principal 'seo_err_nobody', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 7732422b7f56, Line 1
Cannot drop the user 'seo_err_nobody', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 7732422b7f56, Line 1
Cannot drop the schema 'seo_err_noschema', because it does not exist or you do not have permission.
Msg 15007, Level 16, State 1, Server 7732422b7f56, Line 1
'seo_err_nologin' is not a valid login or you do not have permission.

DROP ROLE, ALTER ROLE … ADD MEMBER on a missing role, DROP CERTIFICATE and GRANT SELECT ON OBJECT:: a missing table gave 15151 too, as Cannot drop the role, Cannot alter the role, Cannot drop the certificate and Cannot find the object. The login cases ran on a temporary SQL Server 2022 container of our own, removed afterwards. There, GRANT SELECT ON dbo.events TO app before app had a user in the database gave Cannot find the user 'app', and worked after CREATE USER app FOR LOGIN app. Signed in as app, which has no server permissions:

Msg 15151, Level 16, State 1, Server 54e64f9ad96b, Line 1
Cannot alter the login 'sa', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 54e64f9ad96b, Line 1
Cannot drop the login 'app', because it does not exist or you do not have permission.

That was ALTER LOGIN sa ENABLE, then DROP LOGIN app (its own login). sa was unchanged, and in app’s view of sys.server_principals the only logins were app and sa. DROP LOGIN IF EXISTS failed with a syntax error (156 near 'IF'). SQL Server 2019 and 2025 printed the same messages for the database-level cases.

In Inlet

Inlet doesn’t manage logins and users yet, so run these statements in a query tab, signed in as someone allowed to. When SQL Server refuses, Inlet shows its message with SQL Server error 15151, state 1, severity 16 and links to this page.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel