Example message AppDomain 3 (master.sys[runtime].2) created.
What this message means (plain English)
SQL Server hosts the .NET Common Language Runtime (CLR). When SQL Server needs CLR—for a user assembly or for certain built-in features—it spins up an AppDomain, which is an isolation container inside the SQL Server process where CLR code runs.
That log line says:
- AppDomain 3 → the internal ID SQL Server assigned to this domain.
- (master.sys[runtime].2) → the database and owner that the domain is associated with (here, system-owned objects in
master). - created → SQL Server just initialized this CLR sandbox so something could run in it.
This is informational, not an error. You’ll often see a matching “… unloaded.” later when SQL Server tears it down.
What typically triggers AppDomain creation
- First use of SQLCLR objects in a database (CLR functions, procs, triggers, user-defined aggregates/types).
- Use of features implemented with CLR (e.g.,
geography/geometry/hierarchyid, Policy-Based Management pieces inmsdb, some internal system tasks). - Server startup, database restore/attach, or the first time a database is accessed after restart.
- Toggling
clr enabledor deploying/dropping assemblies.
If you only see a handful of these around startup or when you first call a CLR routine, that’s normal. If you see hundreds of create/unload cycles, that’s a smell you should investigate.
Quick decision guide
- One-off at startup or first use? Safe to ignore.
- Repeated create/unload all day long? Investigate (auto-close, memory pressure, assembly churn, or misconfigured CLR security).
- Failures right after creation? Look for additional messages about assembly load or permission problems.
How to research & troubleshoot (step-by-step, with scripts)
1) Confirm CLR state and basic facts
-- Is CLR enabled at the instance level?
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'clr enabled';
-- CLR properties (version, memory)
SELECT * FROM sys.dm_clr_properties;
-- What CLR app domains exist right now?
SELECT * FROM sys.dm_clr_appdomains;
-- Which assemblies are currently loaded?
SELECT * FROM sys.dm_clr_loaded_assemblies;
-- Memory used by SQLCLR
SELECT type, pages_kb
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%CLR%';
What to look for
clr enabledshould be 1 if you use user assemblies.sys.dm_clr_appdomainsshows the friendly name (oftendb.owner[runtime].N), creation time, and state.sys.dm_clr_loaded_assembliestells you which assemblies loaded and the AppDomain they’re in.
Tip: If you only see system app domains (e.g.,
master.sys[runtime],msdb.dbo[runtime]) and no user assemblies, the message was likely triggered by a built-in feature.
2) Map AppDomains to databases and assemblies
Run this per database where you suspect CLR usage:
-- In the target database context
SELECT a.name AS assembly_name,
a.permission_set_desc,
af.file_id, -- if present
af.content -- varbinary; don't SELECT in SSMS grid unless you need it
FROM sys.assemblies AS a
LEFT JOIN sys.assembly_files AS af ON a.assembly_id = af.assembly_id
ORDER BY a.is_user_defined DESC, a.name;
If you see custom assemblies here, they’re candidates for having triggered the AppDomain.
3) Check for churn in the error log (lots of create/unload)
-- Count AppDomain entries today
CREATE TABLE #elog(LogDate datetime, ProcessInfo nvarchar(50), [Text] nvarchar(max));
INSERT #elog EXEC xp_readerrorlog 0, 1, N'AppDomain';
SELECT COUNT(*) AS occurrences,
MIN(LogDate) AS first_seen,
MAX(LogDate) AS last_seen
FROM #elog;
-- Optional: see hourly pattern
SELECT CONVERT(char(13), LogDate, 120) AS hour_block,
COUNT(*) AS entries
FROM #elog
GROUP BY CONVERT(char(13), LogDate, 120)
ORDER BY hour_block;
DROP TABLE #elog;
Why this matters: rapid create/unload loops can indicate AUTO_CLOSE, memory pressure, frequent assembly redeploys, or databases attaching/detaching.
4) Rule out AUTO_CLOSE (common cause of churn)
When AUTO_CLOSE is ON, closing the last connection to a database can unload its AppDomain; the next connection recreates it.\
SELECT name, is_auto_close_on
FROM sys.databases
WHERE is_auto_close_on = 1; -- anything here should be reviewed
Fix:
ALTER DATABASE [YourDB] SET AUTO_CLOSE OFF WITH NO_WAIT;
5) Check for memory pressure leading to unloads
If memory is tight, SQL Server may reclaim CLR memory and unload domains.
-- Look at CLR memory and overall pressure signals
SELECT * FROM sys.dm_os_memory_clerks WHERE type LIKE '%CLR%';
SELECT * FROM sys.dm_os_ring_buffers WHERE ring_buffer_type = 'RING_BUFFER_RESOURCE_MONITOR';
Fix ideas
- Set a realistic
max server memoryso the OS has headroom. - Reduce the footprint of user assemblies (cache less, dispose objects).
- Add RAM if the box is truly constrained.
6) Look for security/permission problems (2017+)
SQL Server 2017 introduced clr strict security (on by default). Unsigned EXTERNAL_ACCESS or UNSAFE assemblies won’t load.
SELECT name, value_in_use
FROM sys.configurations
WHERE name IN ('clr strict security', 'clr enabled');
If your error log shows “assembly could not be loaded due to security policy” near the AppDomain message:
Preferred fix: sign the assembly and create a certificate/asymmetric key login with UNSAFE ASSEMBLY permission.
Last-resort (not recommended):
EXEC sp_configure 'clr strict security', 0; RECONFIGURE; -- reduces protection
EXEC sp_configure ‘clr strict security’, 0; RECONFIGURE; — reduces protection
7) Identify what code triggered CLR
If it’s your code, it’s easy: call stack points to your CLR object. If you’re not sure:
- Search your code base for
CREATE ASSEMBLY,EXTERNAL NAME, or UDT/aggregate definitions. - Look for built-in features you’re using that rely on CLR in
master/msdb(PBM evaluations,geography/geometrytypes, etc.). - Correlate the spid in the log (
spid144in your screenshot) with session info at the time of creation using monitoring data, default trace, or your server-side traces if you keep them.
Worked examples
Example A: First call to a user CLR function
clr enabledis 1.- You deploy
MyUtilsassembly and createdbo.RegexIsMatchin databaseAppDB. - First user runs:
SELECT dbo.RegexIsMatch('abc', '^[a].*');
SELECT dbo.RegexIsMatch('abc', '^[a].*');
- Error log shows:
AppDomain 7 (AppDB.dbo[runtime].2) created. - You’ll see
MyUtilsinAppDB.sys.assembliesand insys.dm_clr_loaded_assemblies.
Outcome: Expected. No action needed.
Example B: AppDomain thrashes all day long
- Error log contains hundreds of
createdandunloadedentries forSalesDB.dbo[runtime]. - Query shows
SalesDBhasAUTO_CLOSE = ON. - After setting
AUTO_CLOSE OFF, churn stops and CPU “spikes” vanish.
Outcome: Root cause was AUTO_CLOSE.
Example C: Load failures after creation
- You see
created, followed by messages like “Assembly MyVendorTool failed verification…” or “not authorized under CLR strict security”. clr strict security = 1, assembly isEXTERNAL_ACCESSand unsigned.
Outcome: Sign the assembly and grant the certificate/asymmetric key login UNSAFE ASSEMBLY (or work with the vendor to provide a signed build). Avoid disabling strict security.
Preventive & operational tips
- Keep
AUTO_CLOSEOFF for user databases. - Avoid flipping
clr enabledon/off repeatedly in automation. - For user assemblies, prefer SAFE permission set; only use
EXTERNAL_ACCESS/UNSAFEwhen absolutely required, and sign them. - Monitor with a lightweight check:
-- Count AppDomain creations in the last 24h
EXEC xp_readerrorlog 0, 1, N'AppDomain', NULL, DATEADD(day,-1,GETDATE()), NULL, N'desc';
Bottom line
That “AppDomain … created” line is SQL Server telling you it spun up a CLR sandbox. One or two lines are normal. Investigate only when you see frequent create/unload cycles or follow-on errors. Use the steps above to identify the database, the assemblies involved, and the common root causes (auto-close, memory pressure, security policy), then apply the targeted fix.
Discover more from SQLyard
Subscribe to get the latest posts sent to your email.


