Failure to load Report Manager due to truncated UserAgent string

We came across an issue when trying to load Report Manager.  We would get the following exception:

System.ArgumentException: Version string portion was too short or too long. at
System.Version..ctor(String version) at
System.Web.Configuration.HttpCapabilitiesBase.GetClrVersions() at
System.Web.Configuration.HttpCapabilitiesBase.get_ClrVersion() at
Microsoft.ReportingServices.Common.RBRequirements.get_ClientMeetsRequirements() at

In turn, this prevented Report Manager from loading.  The exception itself is occuring within the .NET Framework, not from Reporting Services (System.Web.Configuration.HttpCapabilitiesBase.GetClrVersions).  GetClrVersions is essentially parsing the UserAgent and getting the latest .NET version available on the client side. 

You might be asking why would we care about the client side when I’m trying to load Report Manager which should be processed server side.  If we look at the callstack, we can see that we are building the URL for the Report Builder button.  Report Builder (RB) is a client side tool, hence we need to make sure that you have the proper .NET version on the client so that we can expose RB to you.

What do we do now?  We knew that we were failing when trying to build out the URL, and from the callstack we know it had something to do with the UserAgent.  Unfortunately, the logs don’t tell me what the UserAgent was.  There are many ways to tell what the UserAgent is.  You could use a client side tool like Fiddler to get the HTTP Requests and Responses.  A network trace would also tell you what the HTTP Header information looked like in a Request.  A memory dump when the exception occurs would also show you what the UserAgent looked like as it related to the code.  I decided to go with the Memory Dump route.  You can do this as well by using the SOS extension that ships with the .NET Framework along with WinDBG which is part of the Debugging Tools for Windows.

When I opened the dump, I was immediately placed on the thread that caused the exception.  In this case it was Thread 37.  So, I dumped the Stack Objects for that thread.

0:037> !dso
OS Thread Id: 0x1ab4 (37)
ESP/REG  Object   Name
1110ef94 02817c74 System.ArgumentException
1110efe0 02817c74 System.ArgumentException
1110eff4 02817c74 System.ArgumentException
1110eff8 02817c60 System.Object[]    (System.String[])
1110f008 02817c74 System.ArgumentException
1110f014 02817c74 System.ArgumentException
1110f024 02817c74 System.ArgumentException
1110f02c 02817c74 System.ArgumentException
1110f034 02817c60 System.Object[]    (System.String[])
1110f080 0263534c System.String    Arg_VersionString
1110f088 02817c74 System.ArgumentException
1110f0a4 02815a60 System.String    Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 1.0.3705; .NET CLR 3
1110f0a8 02817380 System.Text.RegularExpressions.Match

From this alone, I can see what the UserAgent string is.  You can also drill a little further into the string itself by Dumping the String Object.  We do this by way of the !do command (do = Dump Object)

0:037> !do 02815a60
Name: System.String
MethodTable: 793308ec
EEClass: 790ed64c
Size: 530(0x212) bytes
String: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 1.0.3705; .NET CLR 3
      MT    Field   Offset                 Type VT     Attr    Value Name
79332b38  4000096        4         System.Int32  1 instance      257 m_arrayLength
79332b38  4000097        8         System.Int32  1 instance      256 m_stringLength
793315cc  4000098        c          System.Char  1 instance       4d m_firstChar
793308ec  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  021c3728:063701d0 100d6880:063701d0 11596040:063701d0 12bad3a0:063701d0 <<
7933151c  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  021c3728:06370874 100d6880:023b880c 11596040:063a4558 12bad3a0:06462cf8 <<

Our string length is 256.  This happens to be length at which ASP.NET currently truncates the UserAgent string.  We can definately see that the UserAgent is being truncted.  So, how do I fix it.

The items within a UserAgent are stored within the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform

NOTE: Please use caution whenever modifying the registry.  I also recommend you export the key before modifying it so that you have a backup if needed.

Here is what this looks like on my machine.


You can have multiple builds for the same version.  For example, I list two entries for the .NET Framework 3.5.  In reality, we only need the latest version.  We ultimately corrected the issue by removing the older builds and making sure we only had the latest build for each version.  With the example above, we would have everything that is listed except for ".NET CLR 3.5.21022".

The reason the exception was being thrown is because the Framework call is using Regular Expressions to pull out the versions (i.e. .NET CLR 3.5, .NET CLR 3.0, .NET CLR 2.0, etc…).  In the UserAgent in question, we had a entry that showed as ".NET CLR 3".  This is what caused the exception.


Adam W. Saxton | Microsoft SQL Server Escalation Services

Comments (2)

  1. Ravi H says:

    Is there a fix available for this in ASP.Net or SSRS ?

    One of our customer has reported a similar issue and they do not want to delete the registry keys.

    Also, what is the cause of the exception ? is it the length or the format of .net version ( having 3 instead of 3.0 )?

    Are there other settings that could cause this error. We have scenarios, where the same client machine shows errors when connecting to one SSRS server but works fine connecting to a different SSRS server.