The login worked. That is the part that throws people. Authentication is already done by the time 916 fires, so resetting the password or checking the login’s status gets you nowhere. What failed is the next step: the server principal tried to enter a specific database, and that database has no user for it to become.
Why This Happens
Three situations produce this one error, and they take three different fixes. The server has already let you in by this point; 916 is a database refusing you, so the answer is always inside that database or inside the tool that asked.
A login and a database user are two different principals joined by a SID. If nothing in the database carries the login’s SID, the join fails and the database refuses you. The login may be perfectly valid at the server door: 916 is the database saying no, not the server.
The query below returns no row whose mapped_login is your login. A user that was dropped while the login lived on looks identical here, and takes the same fix, which is why they are one case rather than two.
The user exists and the mapping is intact, but the permission that lets it in has been taken away. This is the case that confuses people, because everything looks correctly configured until you check the permission itself.
The user IS in the list below with your login in mapped_login, and sys.database_permissions shows CONNECT with state_desc = 'DENY', or simply has no GRANT row for CONNECT at all.
The special case that generates most of the search traffic. Expanding the Databases node makes Object Explorer quietly query every database on the instance for the detail columns it displays, size and collation among them. One database your login cannot reach fails that background query, and SSMS raises 916 about a database you never clicked.
The error names a database you did not open, and it arrives while expanding a node rather than while running a query. Microsoft documents a second trigger with the same shape: CONNECT denied on msdb breaks the Policy Based Management query, and 916 arrives next to a “Failed to retrieve data for this request” dialog.
Microsoft’s reference covers error 916 in full, including the Object Explorer triggers.
Reproduce It in One Batch
This is the exact test I ran to capture the message above, and it doubles as a diagnostic for any login you are troubleshooting:
-- a login that exists on the server and has no user in the target database
CREATE LOGIN ErrDemo916 WITH PASSWORD = '<a strong password>';
EXECUTE AS LOGIN = 'ErrDemo916';
SELECT TOP 1 order_id FROM DemoDatabase.dbo.RlsOrders;
REVERT;
DROP LOGIN ErrDemo916;
That SELECT throws Msg 916, Level 14, State 2 every time, which is the message in the box above. EXECUTE AS is what makes this useful on a real instance: it lets you test as the affected principal without knowing their password, so you can confirm a report of 916 without asking anyone to hand over credentials.
Find the Gap
Check whether the login has a user in the database, and what that user can do:
USE DemoDatabase;
SELECT dp.name AS database_user,
dp.type_desc,
sp.name AS mapped_login,
dp.authentication_type_desc
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON sp.sid = dp.sid
WHERE dp.type IN ('S', 'U', 'G')
ORDER BY dp.name;
No row with your login’s name in mapped_login means no mapping. A row whose database_user exists but whose CONNECT was revoked shows up in sys.database_permissions with state_desc = 'DENY' or simply no GRANT row for CONNECT.
The Fix
No user mapped to the login. Create the mapping and give it what it needs:
USE DemoDatabase;
CREATE USER ErrDemo916 FOR LOGIN ErrDemo916;
ALTER ROLE db_datareader ADD MEMBER ErrDemo916;
CONNECT denied or revoked. Give the permission back:
GRANT CONNECT TO ErrDemo916;
SSMS asked on your behalf. Two honest options: grant the login access to the database SSMS is choking on, or stop SSMS asking the question. In Object Explorer Details (F7), right-click the column headers and remove Collation and the size columns, and the background query that triggers 916 stops running. Granting access is the fix; trimming the columns is the workaround when access is genuinely not supposed to exist.
When It Is Not This
If the database is OFFLINE, RESTORING, SUSPECT or already in SINGLE_USER you get different errors (942, 927, 926 and 924 respectively), not 916. And if the login itself failed you are in 18456 territory before any of this starts. 916 specifically means: server let you in, database did not.
Common Questions
Is this the same as login failed (18456)?
Why does SSMS raise this for a database I never clicked?
Can I just enable the guest user?
The error came from an application with ODBC state 08004, not from SSMS.
USE, a three-part name such as OtherDb.dbo.Table, or a procedure that reaches into another database. That is the shape reproduced above. A database named in the connection string itself fails earlier and differently, with 4060, so 916 from an application points at a statement, not at the connection string.Related Scripts
- Cannot Execute As the Database Principal (Error 15517), the other principal error, and how to tell them apart
- Login Failed (18456), the server-door error this gets confused with
- Cannot Open Database (4060), the connection-string sibling
- Orphaned Users (15023), how mappings break after a restore
- Get User Permissions Audit, one login’s real access in a single script
Leave a Reply