Troubleshooting Guide: Error 12819 – spmigrateusertocontained Fails on Non-Contained Database
Why This Error Happens
Error 12819 occurs because the stored procedure sp_migrate_user_to_contained is designed exclusively for partially or fully contained databases, and it checks the database’s CONTAINMENT property before executing. If the target database was created or left with CONTAINMENT = NONE (the default setting), SQL Server 2025 blocks the migration of logins to contained users since there is no containment boundary to migrate them into. This is not a corruption or permissions issue, but rather a configuration mismatch between the procedure’s requirements and the database’s current containment state.
Step-by-Step Resolution Guide
Step 1: Verify the Current Containment Status
- Open SQL Server Management Studio (SSMS) or Azure Data Studio connected to your SQL Server 2025 instance.
- Run the following query to check the containment level of the target database:
SELECT name, containment, containment_desc
FROM sys.databases
WHERE name = 'YourDatabaseName';
- Confirm that
containment_descreturnsNONE, which confirms the root cause.
Step 2: Enable Contained Database Authentication at the Instance Level
- Before altering the database, ensure the instance-level setting allows contained databases.
- Run the following in a query window with sysadmin privileges:
EXEC sp_configure 'contained database authentication', 1;
RECONFIGURE;
- This step is mandatory on both Windows Server 2025 and Windows 11 local instances, as the feature is disabled by default for security hardening.
Step 3: Alter the Database Containment Setting
- Change the database containment level from
NONEtoPARTIAL(the only supported containment type in SQL Server 2025). - Execute the following T-SQL command:
ALTER DATABASE YourDatabaseName
SET CONTAINMENT = PARTIAL;
- Ensure no active connections are blocking the ALTER statement; if necessary, set the database to
SINGLE_USERmode temporarily:
ALTER DATABASE YourDatabaseName SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
Step 4: Re-run the Migration Procedure
- Once containment is set to
PARTIAL, execute the original migration command again. - Use the following syntax to migrate the specific login to a contained user:
EXEC sp_migrate_user_to_contained
@username = 'YourUserName',
@rename = 'copy_login',
@disablelogin = 'true';
- Switch the database back to
MULTI_USERmode if you changed it in Step 3:
ALTER DATABASE YourDatabaseName SET MULTI_USER;
Alternative or Verification Steps
- Verification: Query
sys.database_principalsfor the migrated user and check that theauthentication_type_desccolumn now readsDATABASEinstead ofINSTANCE, confirming the user is fully contained. - Alternative: If altering containment is not permitted due to organizational policy (e.g., high-availability groups requiring uniform containment settings across replicas), manually create a contained user with a password using
CREATE USER [UserName] WITH PASSWORD = 'StrongPassword123!';instead of relying on the migration procedure.