ALTER USER [name] WITH LOGIN = [name]; remaps it to the login and keeps every permission it already had.You restored a database from another server, the application cannot log in, so you tried to create the user and SQL Server told you it is already there. Both things are true. The user exists in the database and the login exists on the server, and they are not connected to each other.
Why This Happens
Logins and users are matched by SID, not by name. A login lives on the server, a user lives in the database, and the user row stores the SID of the login it belongs to.
Restore that database onto a different server and the user comes with it, still holding the SID of a login that only existed on the old machine. The name matches. The SID does not. The user is orphaned.
Windows logins usually survive this, because their SID comes from Active Directory and is the same everywhere. SQL logins almost never do, because their SID was generated on the original instance.
Find Every Orphan First
Before fixing one, see the whole picture:
SELECT dp.name AS database_user,
dp.type_desc,
dp.sid,
dp.create_date
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON sp.sid = dp.sid
WHERE sp.sid IS NULL
AND dp.type IN ('S', 'U', 'G') -- SQL user, Windows user, Windows group
AND dp.authentication_type_desc IN ('INSTANCE', 'WINDOWS') -- skip WITHOUT LOGIN and contained users
AND dp.name NOT IN ('guest', 'INFORMATION_SCHEMA', 'sys', 'dbo')
ORDER BY dp.name;
Anything listed has permissions inside the database and no way to be reached from outside it. The authentication_type_desc line matters: a user created WITHOUT LOGIN has no login by design and would otherwise show up here as a false orphan.
The Fix
If a login with the same name already exists on the server, point the user at it:
USE YourDb;
GO
ALTER USER [AppUser] WITH LOGIN = [AppUser];
That rewrites the user’s SID to match the login and keeps every permission the user already had. This is the fix in almost every case.
If the login does not exist yet, create it and then remap:
CREATE LOGIN [AppUser] WITH PASSWORD = N'<a real password>';
GO
USE YourDb;
GO
ALTER USER [AppUser] WITH LOGIN = [AppUser];
Do not drop the user. Dropping it destroys its role memberships and object-level permissions, and recreating the user gives you an empty one. People do this because CREATE USER failed and dropping seems like the way to make it succeed. It is the expensive way.
Keeping the Original Password
Recreating a SQL login with a new password breaks every application using the old one. If you still have access to the source server, copy the hash instead of inventing a password:
-- ON THE SOURCE SERVER
SELECT name,
[sid],
password_hash
FROM sys.sql_logins
WHERE name = N'AppUser';
Then on the target, create the login with the original SID so nothing needs remapping at all:
CREATE LOGIN [AppUser]
WITH PASSWORD = 0x0200... HASHED,
SID = 0x1234...,
CHECK_POLICY = OFF;
Creating the login with the original SID is the cleanest migration, because the users in every restored database match it immediately and there is nothing to fix afterwards.
The Old Advice You Will Find
Search results still recommend:
EXEC sp_change_users_login 'Auto_Fix', 'AppUser';
It is deprecated and it guesses. Auto_Fix matches by name and creates the login if one does not exist, which is exactly the assumption that causes trouble when two different accounts share a name across servers. ALTER USER ... WITH LOGIN is explicit, supported, and does the same job without guessing.
Microsoft’s reference covers troubleshooting orphaned users and sp_change_users_login in full.
Stopping It Recurring
- Script logins with their SID and hash as part of any migration, so users land already matched.
- Run the orphan query after every restore from another server. It takes seconds and it finds the problem before an application does.
- Prefer Windows authentication where you can. AD SIDs are consistent across servers, so the whole class of problem does not arise.
Common Questions
Should I just drop the user and recreate it?
ALTER USER ... WITH LOGIN remaps it and keeps everything.Why do Windows logins usually survive a restore?
What about sp_change_users_login Auto_Fix?
ALTER USER ... WITH LOGIN is explicit and supported.I fixed the user and the application still cannot log in.
Related Scripts
- Get Permissions and Role Membership, what the user could do before you touch it
- Get Sysadmin Members, audit who holds the keys after a migration
- Get Orphaned Users, find every one across the instance in a single pass
- Cannot Open Database Requested by the Login (4060), the error an orphaned user usually causes
- Fix Orphaned Users, generates the ALTER USER statements for every orphan it finds
Leave a Reply