{"id":7164,"date":"2026-02-06T11:22:31","date_gmt":"2026-02-06T16:22:31","guid":{"rendered":"https:\/\/andreas-wolter.com\/?p=7164"},"modified":"2026-02-06T11:22:31","modified_gmt":"2026-02-06T16:22:31","slug":"2602_sqlserver2025cu1_containedavailabilitygroup_improvementissues","status":"publish","type":"post","link":"https:\/\/andreas-wolter.com\/en\/2602_sqlserver2025cu1_containedavailabilitygroup_improvementissues\/","title":{"rendered":"SQL Server 2025 CU1 Improvement Allow Creating of Databases within a Contained Availability Group \u2013 current limitations"},"content":{"rendered":"\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-m0cxh8ps-6f808684ed0411e8e99dbe489733f80f\">\n#top .av-special-heading.av-m0cxh8ps-6f808684ed0411e8e99dbe489733f80f{\npadding-bottom:10px;\n}\nbody .av-special-heading.av-m0cxh8ps-6f808684ed0411e8e99dbe489733f80f .av-special-heading-tag .heading-char{\nfont-size:25px;\n}\n.av-special-heading.av-m0cxh8ps-6f808684ed0411e8e99dbe489733f80f .av-subheading{\nfont-size:15px;\n}\n<\/style>\n<div  class='av-special-heading av-m0cxh8ps-6f808684ed0411e8e99dbe489733f80f av-special-heading-h3 blockquote modern-quote  avia-builder-el-0  el_before_av_textblock  avia-builder-el-first '><h3 class='av-special-heading-tag'  itemprop=\"headline\"  >SQL Server 2025 CU1 Improvement Allow Creating of Databases within a Contained Availability Group \u2013 current limitations<\/h3><div class=\"special-heading-border\"><div class=\"special-heading-inner-border\"><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-m0cxgkjy-c935304b4106b45214698f40e83a9894 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>First of all: It&#8217;s always encouraging to see the Product team act on user feedback. SQL Server 2025 CU1 introduces an improvement that allows the creation and restoration of databases within contained availability groups (CAG). This is a step in the right direction, but as you\u2019ll see, there are still some bumps to smooth out. Keep the feedback coming (here: <a href=\"https:\/\/feedback.azure.com\/d365community\/idea\/07f0807c-6825-f011-9d47-7c1e52d4bdd3\" target=\"_blank\" rel=\"noopener\">Allow creation and restore of databases in contained availability group<\/a>) \u2014 progress is happening, but we\u2019re not quite there yet.<\/p>\n<p style=\"padding-left: 40px;\"><strong><em>Background<br \/>\n<\/em><\/strong>The overarching goal is to make Contained Availability Groups (CAGs) fully transparent to applications, particularly in setup routines.<br \/>\nI\u2019ve previously written about the advantages and limitations of using SQL Server Contained Availability Groups here: <a href=\"https:\/\/andreas-wolter.com\/en\/2504_sqlserver_contained_availability_groups\/\">Why you should use SQL Server contained availability groups to save time \u2013 and why consultants may not tell you about them<\/a><\/p>\n<h2>What\u2019s new in SQL Server 2025 CU1<\/h2>\n<p>The recently published <a href=\"https:\/\/learn.microsoft.com\/en-us\/troubleshoot\/sql\/releases\/sqlserver-2025\/cumulativeupdate1#4860665\" target=\"_blank\" rel=\"noopener\">first Cumulative Update (CU1) for SQL Server 2025,<\/a> includes a Fix called: <em>Enables creating or restoring the database by using a listener for Container Availability Group Connection. This feature lets Contained AG users create and restore the database without a connection to the SQL instance.<\/em><\/p>\n<p>The documentation now contains an entry <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/database-engine\/availability-groups\/windows\/contained-availability-groups-overview?view=sql-server-ver16#enable-database-creation-or-restoration-in-contained-availability-group-sessions\" target=\"_blank\" rel=\"noopener\">Enable database creation or restoration in contained availability group sessions<\/a>. It states: <em>\u201cThis enhancement streamlines workflows for users assigned the appropriate roles, allowing seamless operations within contained AG environments.\u201d<\/em><\/p>\n<p>However, I\u2019d advise a little caution with the word &#8220;seamless.&#8221; In this article I will take a deeper look at how this works \u2014 and where it still needs some polish.<\/p>\n<h2>Creating a database from a connection to a contained Availability Group &#8211; How does it actually work?<\/h2>\n<p>The documentation is not very elaborate about this, so allow me to go over the process of creating or restoring a database from a connection to a contained Availability Group:<\/p>\n<p>Requirement: a Login with at l.east CREATE ANY DATBASE permission inside the Contained AG\u2019s context<\/p>\n<ul>\n<li>Run EXECUTE sp_set_session_context @key = N&#8217;allow_cag_create_db&#8217;, @value = 1;<\/li>\n<li>Run a CREATE DATABASE statement \u2013 or, alternatively, run a RESTORE DATABASE-statement.<\/li>\n<li>Then run BACKUP DATABASE to establish the Log Chain base (same as you do when putting a database into any Availability Group).<\/li>\n<li>Then add the database to the Availability Group.<\/li>\n<\/ul>\n<p>So, contrary to what some might expect, you can&#8217;t simply create a database within the context of the AG and expect it to be part of the AG immediately. It must be manually added to the availability group afterward. Until that step is done, the database will only be visible on the host machine.(!) \u2013 like the screenshot below shows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7165 alignnone\" src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG-1030x683.png\" alt=\"\" width=\"777\" height=\"515\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG-1030x683.png 1030w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG-300x199.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG-768x509.png 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG-705x468.png 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer2025CU1_CreateDatabase_in_CAG.png 1298w\" sizes=\"auto, (max-width: 777px) 100vw, 777px\" \/><\/p>\n<p>Now that we understand the process, let\u2019s investigate the steps closely and how they affect usability:<\/p>\n<h2>Gotcha #1: special command required<\/h2>\n<p>Before a user can create or restore a database within a contained AG connection, they need to run a special command:<\/p>\n<p><em>EXECUTE sp_set_session_context @key = N&#8217;allow_cag_create_db&#8217;, @value = 1;<\/em><\/p>\n<p>While this looks easy, it is a blocker to any install-routine to just roll out databases as usual. I cannot imagine application vendors willing to adjust their setup routines to:<br \/>\nA) check if the connection is against a Contained AG<br \/>\nB) if so, run that command before starting the main deployment<br \/>\nc) Don\u2019t forget to then also add the database to the CAG<\/p>\n<p>In my opinion, at this stage, this functionality will be useful mainly for DBAs who are accustomed to running ad-hoc scripts, but it doesn&#8217;t help with streamlining deployment for applications or vendors.<\/p>\n<p>I wonder why this session context is required at all and not the default. That might be just because of the rush the team was under.<\/p>\n<h3>My recommendation to the Microsoft product team:<\/h3>\n<p>To make this work seamless for setup routines, there can\u2019t be any special commands required. I know, there is much more to it, and we will get to it further down.<\/p>\n<h2>Gotcha #2: special proc sp_sysutility_cag_create_db lacks basic checks<\/h2>\n<p>To simplify the 4-step process from above), Microsoft has provided a stored procedure: dbo.sp_sysutility_cag_create_db, found in <em>msdb<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-7169\" src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1-1030x344.png\" alt=\"\" width=\"1030\" height=\"344\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1-1030x344.png 1030w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1-300x100.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1-768x256.png 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1-705x235.png 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/02\/2026-01_SQLServer_sp_sysutility_cag_create_db-1.png 1100w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/p>\n<p>However, this stored procedure is not documented (only mention in this technet blog: <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/creating-a-contained-availability-group-and-enabling-database-creation-via-cag-l\/4486543\" target=\"_blank\" rel=\"noopener\">Creating a Contained Availability Group and Enabling Database Creation via CAG Listener<\/a>). Also, it simply automates the steps I outlined above without any error handling or checks. It&#8217;s risky to use without caution.<\/p>\n<p>This is what it does when you try to add a database which already exists:<\/p>\n<p style=\"padding-left: 40px;\">CREATE DATABASE [DBAlreadyInCAG]<\/p>\n<p style=\"padding-left: 40px;\"><em>Msg 1801, Level 16, State 3, Line 29<\/em><\/p>\n<p style=\"padding-left: 40px;\"><em>Database &#8216;DBAlreadyInCAG&#8217; already exists. Choose a different database name.<\/em><\/p>\n<p style=\"padding-left: 40px;\">ALTER DATABASE [DBAlreadyInCAG] SET RECOVERY FULL<\/p>\n<p style=\"padding-left: 40px;\">BACKUP DATABASE [DBAlreadyInCAG] TO DISK = N&#8217;NUL&#8217;<\/p>\n<p style=\"padding-left: 40px;\"><em>Processed 424 pages for database &#8216;DBAlreadyInCAG&#8217;, file &#8216;DB11&#8217; on file 1.<\/em><\/p>\n<p style=\"padding-left: 40px;\"><em>Processed 1 pages for database &#8216;DBAlreadyInCAG&#8217;, file &#8216;DB11_log&#8217; on file 1.<\/em><\/p>\n<p style=\"padding-left: 40px;\"><em>BACKUP DATABASE successfully processed 425 pages in 0.016 seconds (207.122 MB\/sec).<\/em><\/p>\n<p style=\"padding-left: 40px;\">use master; ALTER AVAILABILITY GROUP [CAG1] add DATABASE [DBAlreadyInCAG]<\/p>\n<p style=\"padding-left: 40px;\"><em>Msg 35280, Level 16, State 2, Line 29<\/em><\/p>\n<p style=\"padding-left: 40px;\"><em>Database &#8216;DBAlreadyInCAG&#8217; cannot be added to availability group &#8216;CAG1&#8217;.\u00a0 The database is already joined to the specified availability group.\u00a0 Verify that the database name is correct and that the database is not joined to an availability group, then retry the operation.<\/em><\/p>\n<ul>\n<li>Well, it tried \ud83d\ude42 &#8211; It could have checked if the DB is already inside the CAG instead though. Now it <u>broke the Backup chain by creating another Backup<\/u> that the DBA won\u2019t know about and not storing it anywhere. Worst case this can lead to data loss(!).<\/li>\n<\/ul>\n<h2>Gotcha #3: dbo.sp_sysutility_cag_create_db prone to command injection and lacks errorhandling<\/h2>\n<p>Maybe the procedure was no meant to be released yet. I am not sure.<br \/>\nBut have a look at the code:<\/p>\n<p style=\"padding-left: 40px;\">CREATE\u00a0\u00a0 PROCEDURE dbo.sp_sysutility_cag_create_db<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0 @database_name\u00a0 sysname,<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0 <strong>@createdb_sql<\/strong> NVARCHAR(MAX) = NULL<\/p>\n<p style=\"padding-left: 40px;\">AS<\/p>\n<p style=\"padding-left: 40px;\">BEGIN<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET NOCOUNT ON<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DECLARE @fIsContainedAGSession int<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXECUTE @fIsContainedAGSession = sys.sp_MSIsContainedAGSession<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (@fIsContainedAGSession = 1)<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BEGIN<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DECLARE @SQL NVARCHAR(MAX);<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXEC sp_set_session_context @key = N&#8217;allow_cag_create_db&#8217;, @value = 1;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 IF @createdb_sql IS NULL<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET @SQL = &#8216;CREATE DATABASE &#8216; + QUOTENAME(@database_name);<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ELSE<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <strong>SET @SQL = @createdb_sql;\u00a0 <\/strong><\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PRINT @SQL<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <strong>EXEC sp_executesql @SQL;\u00a0 <\/strong><\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET @SQL = &#8216;ALTER DATABASE &#8216; + QUOTENAME(@database_name) + &#8216; SET RECOVERY FULL&#8217;;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PRINT @SQL<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXEC sp_executesql @SQL;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET @SQL = &#8216;BACKUP DATABASE &#8216; + QUOTENAME(@database_name) + &#8216; TO DISK = N&#8221;NUL&#8221;&#8217;;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PRINT @SQL<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXEC sp_executesql @SQL;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DECLARE @AG_Name sysname;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 set @AG_Name = (SELECT name FROM sys.availability_groups ags<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 INNER JOIN sys.dm_exec_sessions des ON ags.group_id = des.contained_availability_group_id<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WHERE @@SPID = des.session_id);<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET @SQL = &#8216;use master; ALTER AVAILABILITY GROUP &#8216; + QUOTENAME(@AG_Name) + &#8216; add DATABASE &#8216; + QUOTENAME (@database_name)<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PRINT @SQL<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXEC sp_executesql @SQL;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EXEC sp_set_session_context @key = N&#8217;allow_cag_create_db&#8217;, @value = 0;<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 END<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ELSE<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BEGIN<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RAISERROR(&#8216;This can only be used with a contained availability group connection.&#8217;, 16, 1);<\/p>\n<p style=\"padding-left: 40px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 END<\/p>\n<p style=\"padding-left: 40px;\">END<\/p>\n<p>The <em>@createdb_sql<\/em> variable, which for some reason is exposed as an input-parameter, can be exploited to execute arbitrary SQL code if injected through a vulnerable interface. While it doesn\u2019t directly elevate privileges thanks to the fact that <em>sp_executesql<\/em> breaks ownership-chaining and proper use of QUOTENAME(), it does present a risk if used within workflows that pull values from a table or other sources.<\/p>\n<h3>My recommendation to the Microsoft product team:<\/h3>\n<p>Personally, I would vouch to get rid of this proc altogether. The benefit is too small. Any DBA can create this proc with proper custom error handling. If anything, it should be a proper system stored procedure, not requiring access to msdb and only allow execution to Logins with CREATE ANY DATABASE-permission.<\/p>\n<h2>Gotcha #4 and 5: One can add ANY database to ANY Availability Group<\/h2>\n<p>This is easily a double issue:<\/p>\n<p>Once your session has the session context <em>allow_cag_create_db<\/em> enabled, there is nothing to stop you from adding <u>any<\/u> database to your Contained Availability Group. \u2013 As long as the database is prepared with a full Backup \u2013 which all production databases should be.<\/p>\n<p>In fact, you could even add it to <u>any other<\/u> availability group (no matter, if contained or not!), if you knew its name.<\/p>\n<p>This can be considered a security issue since this could allow a vendor to gain access to a database that does not belong to him. (CAG\u2019s do not pose a security boundary per se, but they can easily be perceived as such and do help a lot. Therefore, I will not go into details how the boundary can be crossed here.)<\/p>\n<p>All it takes is running ALTER AVAILABILITY GROUP <strong>[CAGOther]<\/strong> add DATABASE <strong>[RandomDatabaseNameThatExists] <\/strong>with any know database name. The statement does not check permissions.<\/p>\n<ul>\n<li>You will then not see the database if it is in a different CAG now, but hey, you confuse the hell out of your DBA \ud83d\ude42<\/li>\n<\/ul>\n<h3>My recommendation to the Microsoft product team:<\/h3>\n<p>SQL Server should have an owner for Availability Groups so you can limit who can do what with which AG. This is not a new request. But with contained AGs this becomes much more important.<\/p>\n<h2>Gotcha #6: Databases are created on the host but not visible in sys.databases<\/h2>\n<p>I can\u2019t blame the product team for this, as this is a touch nut to crack, but it should be understood: a user who is connected to a contained AG Listener, can only see databases that are part of this CAG. But when the user creates a new database, it will only show up on the host \u2013 until it gets added to the CAG.<\/p>\n<p>This can easily be confusing since you can\u2019t easily check if your database already exists and so on.<\/p>\n<h3>My recommendation to the Microsoft product team:<\/h3>\n<p>One solution might be that the person which has the CREATE ANY DATABASE permission should be able to see any database it created, even the ones that are not inside the CAG yet. Of course, with a special remark like \u201cunjoined\u201d. But again, this is not an easy challenge.<\/p>\n<p>I would rather go for a truly transparent, \u201cseamless\u2019, to resuse the words from BOL \ud83d\ude09 database-creation, which wraps all these 3 steps (Create DB, Backup DB, Add DB to CAG) under the CREATE DATABASE command \u2013 WHEN it\u2019s run under the context of the CAG. In one Transaction. Either it all works or nothing.<\/p>\n<h1>Conclusion<\/h1>\n<p>Don\u2019t get me wrong: I am super happy that the product team has been able to make a move in the right direction in this specific challenge. I just want to make sure that the challenges for application vendors are clear and that this will continue to see improvements.<\/p>\n<p>I have reached out to the team about these issues and shortcomings, and they are looking into it. That\u2019s all I can say for now.<\/p>\n<p>If you think you want to have someone get your High Availability setup right, feel free to <a href=\"https:\/\/andreas-wolter.com\/en\/contact\/\">reach out<\/a>. I work with former engineers and product managers from the Microsoft Product team, and we are happy to help.<\/p>\n<p>Andreas<\/p>\n<\/div><\/section>\r\n\r\n<div  class='hr av-baku8u-c77559299fb7cb036a9bcb2d27e7c839 hr-default  avia-builder-el-2  el_after_av_textblock  el_before_av_social_share '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n<div  class='av-social-sharing-box av-5n5vpa-78ffdd9d224b4a246af65bdc00dce900 av-social-sharing-box-default  avia-builder-el-3  el_after_av_hr  el_before_av_hr  av-social-sharing-box-fullwidth'><div class=\"av-share-box\"><h5 class='av-share-link-description av-no-toc '>Share article<\/h5><ul class=\"av-share-box-list noLightbox\"><li class='av-share-link av-social-link-facebook' ><a target=\"_blank\" aria-label=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https:\/\/andreas-wolter.com\/en\/2602_sqlserver2025cu1_containedavailabilitygroup_improvementissues\/&#038;t=SQL%20Server%202025%20CU1%20Improvement%20Allow%20Creating%20of%20Databases%20within%20a%20Contained%20Availability%20Group%20%E2%80%93%20current%20limitations\" aria-hidden=\"false\" data-av_icon=\"\ue8f3\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Facebook\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Facebook<\/span><\/a><\/li><li class='av-share-link av-social-link-twitter' ><a target=\"_blank\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=SQL%20Server%202025%20CU1%20Improvement%20Allow%20Creating%20of%20Databases%20within%20a%20Contained%20Availability%20Group%20%E2%80%93%20current%20limitations&#038;url=https:\/\/andreas-wolter.com\/en\/?p=7164\" aria-hidden=\"false\" data-av_icon=\"\ue8f1\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Twitter\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Twitter<\/span><\/a><\/li><li class='av-share-link av-social-link-linkedin' ><a target=\"_blank\" aria-label=\"Share on LinkedIn\" href=\"https:\/\/linkedin.com\/shareArticle?mini=true&#038;title=SQL%20Server%202025%20CU1%20Improvement%20Allow%20Creating%20of%20Databases%20within%20a%20Contained%20Availability%20Group%20%E2%80%93%20current%20limitations&#038;url=https:\/\/andreas-wolter.com\/en\/2602_sqlserver2025cu1_containedavailabilitygroup_improvementissues\/\" aria-hidden=\"false\" data-av_icon=\"\ue8fc\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on LinkedIn\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on LinkedIn<\/span><\/a><\/li><\/ul><\/div><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-4ofg9q-c2108540b480aba02923089240a3a176\">\n#top .hr.hr-invisible.av-4ofg9q-c2108540b480aba02923089240a3a176{\nheight:50px;\n}\n<\/style>\n<div  class='hr av-4ofg9q-c2108540b480aba02923089240a3a176 hr-invisible  avia-builder-el-4  el_after_av_social_share  el_before_av_comments_list '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n<div  class='av-buildercomment av-284ftq-f5a1564cd6b8ffad6ce835e2d40de4b7  av-blog-meta-author-disabled av-blog-meta-html-info-disabled'><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":4,"featured_media":7165,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[98,57,383],"tags":[378,384,206],"class_list":["post-7164","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hadr-alwayson-en","category-security-en","category-sql-server-2025","tag-availability-groups","tag-hadr","tag-sql-security"],"_links":{"self":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/comments?post=7164"}],"version-history":[{"count":2,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7164\/revisions"}],"predecessor-version":[{"id":7174,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7164\/revisions\/7174"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media\/7165"}],"wp:attachment":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media?parent=7164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/categories?post=7164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/tags?post=7164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}