Behavior
When browsing to specific resources, such as “http(s)://
However, when browsing to a directory, such as “http(s)://
True error cannot be seen until “customErrors mode=”Off” in “web.config”:
<system.web>
<customErrors mode="Off" />
</system.web>
After doing this we can see the actual error:
"Could not load file or assembly 'System.Runtime.Serialization’. The file or directory is corrupted and unreadable 0x80070570"
Source File: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config Line:97
Found in Event Viewer same thing:
Event code: 3008
Event message: A configuration error has occurred.
Process information:
Process ID: 97096
Process name: w3wp.exe
Account name: IIS APPPOOL\DefaultAppPool
Exception information:
Exception type: ConfigurationErrorsException
Exception message: Could not load file or assembly 'System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The file or directory is corrupted and unreadable. (Exception from HRESULT: 0x80070570) (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config line 97)
at System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
at System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai)
at System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig)
at System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies()
at System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded)
at System.Web.Compilation.BuildManager.ExecutePreAppStart()
at System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException)
Tested with new IIS site and new App Pool. Created “test.txt” and added to Default Document. Same issue. Issue is System-wide
First thought is that there is something wrong with “System.Runtime.Serialization.dll” or something wrong with the ROOT web.config.
Checked the ROOT web.config located at “C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config” around line 97.
However, when checked with another machine, file seems to be fine and dll is there.
The other thing that we tried was to copy the “System.Runtime.Serialization.dll” from a working Server to the non-working Server.
Copied “C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.Serialization\v4.0_4.0.0.0__b77a5c561934e089\System.Runtime.Serialization.dll” from working to non-working Server, same location.
Did iisreset /noforce
Tested. Issue persisted.
At this point, we enabled Fusion Log & Repro issue.
Fusion Log shows that it finds “System.Runtime.Serialization” from GAC at:“C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.Serialization\v4.0_4.0.0.0__b77a5c561934e089\System.Runtime.Serialization.dll”.
However, for some reason, we ended up with:”ERR: Unrecoverable error occurred during pre-download check (hr=0x80070570)”.
This supports the theory that “System.Runtime.Serialization.dll” is corrupted. However, replacing it with the dll from working Server should have fixed this.
Next logical step was to use “gacutil /if C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll” to install “System.Runtime.Serialization.dll”. Although I would have expected that copying and pasting from working to non-working should have had the same effect.
For some reason, we could not do that at the time.
By this point we ran sfc /scannow
. But it did not find anything to fix.
The very next thing to try is chkdsk c: /f
. But this runs at reboot, so we could not test at the moment.
In the meantime, we took PROCMON trace.
Trace shows the w3wp.exe finds “System.Runtime.Serialization.dll” in GAC from “C:\Windows\Microsoft.NET\Framework64\v4.0.30319\”.
However it also find its native image, which has priority. It finds “System.Runtime.Serialization.ni.dll” in “ “C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Runteb92aa12#\1bed881d4e49318171274a4f08663898”.
Runtime first checks if there is native image in GAC, if there is, it takes it, if not, if will find the actual dll.
Native images are created by NGEN to convert the dll to machine code in advanced. So, that your app don’t need to convert the source code of that dll to machine code every time on start.
The problem here is that the native image is corrupted!
We need to delete the “System.Runtime.Serialization.ni.dll” located at “C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Runteb92aa12#\1bed881d4e49318171274a4f08663898\System.Runtime.Serialization.ni.dll”.
By doing so, it will force application to use the actual dll.
We also can delete native image, the “System.Runtime.Serialization.ni.dll”, and then re-generate it with NGEN.
CMD ADMIN and change directory to “ C:\Windows\Microsoft.NET\Framework64\v4.0.30319”.
Run:
ngen install System.Runtime.Serialization
iisreset /noforce
Done.
Do not underestimate PROCMON :)