FIX: Error messages after SQL Server has been running for some time on Windows Server 2003 or on Windows 2000: "Failed to load FileName.dll" and "Attempts to load any type of dll might fail within the SQL Server process"

Applies to: SQL Server 2008 R2 StandardSQL Server 2008 R2 WorkgroupSQL Server 2008 R2 Developer More

Symptoms


When you run Microsoft SQL Server on a Windows Server 2003-based computer or on a Windows 2000-based computer, you may receive an error message that contains the following error messages:
  • Failed to load FileName.dll
  • Attempts to load any type of dll might fail within the SQL Server process with errors pointing to LoadLibrary failure.
This problem usually occurs after SQL Server has been running for some time.

The complete error message that you receive resembles the following:
Exception Type: Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException
Message: The read on the database failed. Reason: Failed to load Msxmlsql.dll.
Data: System.Collections.ListDictionaryI,4092,NULL,NULL,2007-04-13 09:44:11.640,DB\SQLServer5,warning,2007-04-13 09:44:13.153,
The activated proc [dbo].[sp_sysmail_activate] running on queue msdb.dbo.ExternalMailQueue output the following: 'The service queue "ExternalMailQueue" is currently disabled.'

Attempts to use XML related activity in TSQL fails.
Msg 6610, Level 16, State 1, Procedure sp_xml_preparedocument, Line 1
Failed to load Msxmlsql.dll.
Msg 6607, Level 16, State 3, Procedure
sp_xml_removedocument, Line 1 sp_xml_removedocument: The value supplied for parameter number 1 is invalid.

Attempts to load any type of dll might fail within the SQL Server process with errors pointing to LoadLibrary failure.
Attempts to use extended stored procedures will result in

Msg 0, Level 16, State 0, Procedure xp_ss_backup, Line 1
Cannot load the DLL C:\Program Files\Microsoft SQL Server\MSSQL\Binn\SQLsafe_ExtendedStoredProc.dll, or one of the DLLs it references. Reason: 1114(A dynamic link library (DLL) initialization routine failed.).

Error: 18210, Severity: 16, State: 1.
BackupVirtualDeviceSet::Initialize: CoCreateInstance failure on backup device 'd4630f27-03a1-47ae-b7a7-4813a6809908'. Operating system error 0x8007045a(A dynamic link library (DLL) initialization routine failed.).

Error: 6512, Severity: 16, State: 27.
Failed to initialize the Common Language Runtime (CLR) v2.0.50727 with HRESULT 0x80004005. You need to restart SQL Server to use CLR integration features.

 

Cause


This problem occurs because no thread local storage (TLS) slot is available for the SQL Server process (Sqlservr.exe). This is a problem in Windows Server 2003 and in Windows 2000.

When SQL Server unloads a DLL, the TLS slots that the DLL uses may not be released because of a problem in the TlsFree function. If SQL Server frequently loads various DLLs, and then unloads these DLLs, these DLLs use up all the available TLS slots. Eventually, SQL Server can no longer load a DLL that requires TLS slots.

Resolution


Note This resolution is only for Windows Server 2003. If you are using Windows 2000, follow the steps in the "Workaround" section."

Hotfix information for Windows Server 2003

A supported hotfix is available from Microsoft. However, this hotfix is intended to correct only the problem that is described in this article. Apply this hotfix only to systems that are experiencing this specific problem. This hotfix might receive additional testing. Therefore, if you are not severely affected by this problem, we recommend that you wait for the next software update that contains this hotfix.

If the hotfix is available for download, there is a "Hotfix download available" section at the top of this Knowledge Base article. If this section does not appear, contact Microsoft Customer Service and Support to obtain the hotfix.

Note If additional issues occur or if any troubleshooting is required, you might have to create a separate service request. The usual support costs will apply to additional support questions and issues that do not qualify for this specific hotfix. For a complete list of Microsoft Customer Service and Support telephone numbers or to create a separate service request, visit the following Microsoft website: Note The "Hotfix download available" form displays the languages for which the hotfix is available. If you do not see your language, it is because a hotfix is not available for that language.
Prerequisites
You must have Windows Server 2003 Service Pack 2 installed on the server.

For more information, click the following article number to view the article in the Microsoft Knowledge Base:

889100 How to obtain the latest service pack for Windows Server 2003

Restart information
You must restart the computer after you apply this hotfix.
Hotfix replacement information
This hotfix does not replace any other hotfixes.
File information
The English version of this hotfix has the file attributes (or later file attributes) that are listed in the following table. The dates and times for these files are listed in Coordinated Universal Time (UTC). When you view the file information, it is converted to local time. To find the difference between UTC and local time, use the Time Zone tab in the Date and Time item in Control Panel.

Windows Server 2003 with Service Pack 2, x86-based versions
File nameFile versionFile sizeDateTimePlatform
Ntkrpamp.exe5.2.3790.41772,348,03229-Oct-200719:01x86

Windows Server 2003 with Service Pack 2, x64-based versions
File nameFile versionFile sizeDateTimePlatform
Hal.dll5.2.3790.4225280,06428-Jan-200810:42x64
Ntkrnlmp.exe5.2.3790.42254,603,90428-Jan-200810:42x64
Ntoskrnl.exe5.2.3790.42254,533,76028-Jan-200810:42x64

Windows Server 2003 with Service Pack 2, IA64-based versions
File nameFile versionFile sizeDateTimePlatform
Ntdll.dll5.2.3790.42251,636,86428-Jan-200810:40IA-64
Ntkrnlmp.exe5.2.3790.42256,568,96028-Jan-200810:40IA-64

Workaround


You can use one of the following methods to work around this problem. We recommend that you use method 1 because the extended stored procedure feature may be removed in future releases of SQL Server.

Method 1

  1. Use the sp_OACreate stored procedure to determine the DLLs that SQL Server loads into the SQL Server process. To do this, follow these steps:
    1. Open SQL Profiler, and then connect to the instance of SQL Server.
    2. In the Trace Properties dialog box, specify the name of the trace, specify the location where SQL Profiler saves the trace, and then click Run.
    3. After you run SQL Profiler for some time, analyze the trace to locate the occurrences of the sp_OACreate stored procedure.
    4. Notice the first parameter of each occurrence of the sp_OACreate stored procedure.

      Note The first parameter indicates the programmatic identifier (ProgID) of the OLE object or the class identifier (CLSID) of the OLE object.
    5. Determine the DLL that contains this OLE object.
    Note You can use SQL Profiler to monitor the instance of SQL Server when you start the SQL Server service.
  2. Make sure that you have enabled the OLE Automation procedures option.
    For more information about how to determine whether the OLE Automation procedures option is enabled and how to enable the OLE Automation procedures option, visit the following Microsoft Develop Network (MSDN) website:
  3. In SQL Server Management Studio of SQL Server 2008 R2, of SQL Server 2008, or of SQL Server 2005 or in SQL Query Analyzer of SQL Server 2000, run the following statements.

    Note  As an example, the following code shows how to load the Wbemdisp.dll file.
    DROP PROC sp_Load_Dll
    GO
    CREATE PROC sp_Load_Dll
    AS
    declare @WmiServiceLocator int, @hr int
    exec @hr = sp_OACreate 'WbemScripting.SWbemLocator', @WmiServiceLocator output
    if @hr = 0
    raiserror ( 'wbemdisp.dll loaded into sql address space by startup procedure sp_Load_Dll, Object Info: %d' , 10 , 1 , @WmiServiceLocator) --WITH LOG
    WHILE 1=1
    WAITFOR DELAY '01:00:00'
    GO
    EXEC sp_procoption 'sp_Load_Dll' , 'startup' , 'true'
    GO
    The statements create a stored procedure. The statements also enable the stored procedure to run when the SQL Server service starts. This stored procedure performs the following operations:
    • Loads the Wbemdisp.dll file.
    • Keeps the Wbemdisp.dll file in memory because the statements do not exit.
    As long as the Wbemdisp.dll file is in memory, other statements do not load the Wbemdisp.dll file again. Therefore, SQL Server does not call the TlsAlloc function and the TlsFree function for the Wbemdisp.dll file.

    Note You must update the code to load the DLLs that you determined in step 1.
  4. Add the statements to the sp_Load_Dll stored procedure in step 3. These statements load the DLLs that you determined in step 1.
  5. Restart the SQL Server service.
  6. Verify that SQL Server loads the Wbemdisp.dll file in memory. To do this, follow these steps:
    1. Open the SQL Server error log file.
    2. Search for the following message:
      wbemdisp.dll loaded into sql address space by startup procedure sp_Load_Dll
      Note This message indicates that SQL Server has loaded the Wbemdisp.dll file.
    3. At a command prompt, run the following command:
      tasklist /m
    4. In the result that you obtain, locate the Sqlservr.exe process, and then verify that the Wbemdisp.dll file is listed.

      Note If the Wbemdisp.dll file is listed, SQL Server has loaded the Wbemdisp.dll file.

Method 2

  1. Use the sp_OACreate stored procedure to determine the DLLs that SQL Server loads into the SQL Server process. To do this, follow these steps:
    1. Open SQL Profiler, and then connect to the instance of SQL Server.
    2. In the Trace Properties dialog box, specify the name of the trace, specify the location where SQL Profiler saves the trace, and then click Run.
    3. After you run SQL Profiler for some time, analyze the trace to locate the occurrences of the sp_OACreate stored procedure.
    4. Notice the first parameter of each occurrence of the sp_OACreate stored procedure.

      Note The first parameter indicates the programmatic identifier (ProgID) of the OLE object or the class identifier (CLSID) of the OLE object.
    5. Determine the DLL that contains this OLE object.
    Note You can use SQL Server Profiler to monitor the instance of SQL Server when you start the SQL Server service.
  2. Create an extended stored procedure. The extended stored procedure contains a function that loads the DLLs that you determined in step 1.
  3. Add the extended stored procedure to SQL Server.
  4. In SQL Server, use the sp_addextendedproc system stored procedure to register the function in the extended stored procedure.
  5. Use the sp_procoption stored procedure to enable the extended stored procedure to automatically start when the SQL Server service starts.
  6. Restart the SQL Server service.
When SQL Server executes the function in the extended stored procedure, SQL Server loads the DLLs by calling the LoadLibrary API.

Status


This is not a problem in SQL Server. This is a problem in Windows Server 2003 and in Windows 2000. This problem does not occur in Windows Vista or in Windows Server 2008.

References


For more information about the TlsAlloc function, visit the following Microsoft Developer Network (MSDN) website: For more information about the TlsFree function, visit the following MSDN website: For more information about the sp_OACreate stored procedure, visit the following MSDN website: