[Bug]: BC 28.5 on-prem — Invoke-NAVApplicationDatabaseConversion fails with TypeInitializationException in OpenTelemetry (regression vs 28.3)
Nobody has claimed this yet.
- Dominant language
- AL
- Stars
- 683
- Forks
- 459
- Avg merge
- 3d 26m
- Merged PRs (30d)
- 633
Description
Describe the issue
On Business Central 28.5 on-premises (build 28.0.54016.0), every Management cmdlet that constructs a NavEnvironment fails immediately when executed from powershell.exe.
Invoke-NAVApplicationDatabaseConversion: The type initializer for
'OpenTelemetry.Instrumentation.Http.Implementation.HttpHandlerDiagnosticListener' threw an exception.
Event Viewer:
TypeLoadException: Could not load type 'System.Diagnostics.ActivitySourceOptions'
from assembly 'System.Diagnostics.DiagnosticSource, Version=8.0.0.0, ...'
Stack:
OpenTelemetry.Trace.ActivitySourceFactory.Create
-> OpenTelemetry.Instrumentation.Http.Implementation.HttpHandlerDiagnosticListener..cctor()
-> OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation
-> Microsoft.BusinessCentral.Telemetry.OpenTelemetry.OpenTelemetrySpanLogger..ctor
-> Microsoft.Dynamics.Nav.Diagnostic.NavOpenTelemetryLogger..ctor
-> Microsoft.Dynamics.Nav.Runtime.NavEnvironment..ctor
-> InvokeNAVApplicationDatabaseConversion.InternalProcessRecord()
Root cause analysis
This is a regression introduced in 28.5. Comparing two servers with otherwise identical configuration (Windows Server 2022, .NET Framework 4.8 release 528449, Windows PowerShell 5.1, same side-by-side BC installs):
28.3 — 28.0.52201.0 (works) |
28.5 — 28.0.54016.0 (fails) |
|
|---|---|---|
System.Diagnostics.DiagnosticSource |
10.0.0.0 | 10.0.0.0 |
OpenTelemetry.Instrumentation.Http |
1.9.0.41 | 1.16.0.1135 |
OpenTelemetry.Instrumentation.Http was upgraded from 1.9.0.41 to 1.16.0.1135. Version 1.16 references System.Diagnostics.DiagnosticSource 8.0.0.0 and requires the ActivitySource API surface from 9.x/10.x in the static constructor of HttpHandlerDiagnosticListener. Version 1.9 did not touch that code path, so the mismatch was harmless.
Correct binding redirects do exist:
Service\Microsoft.Dynamics.Nav.Server.exe.config—System.Diagnostics.DiagnosticSource0.0.0.0-10.0.0.0->10.0.0.0Service\Management\Microsoft.Dynamics.Nav.Management.dll.config— same redirects
The NST service works because it is an .exe and reads its own .exe.config. However, .NET Framework never reads *.dll.config — configuration is resolved only from <process>.exe.config. When Management cmdlets are loaded into powershell.exe, no redirect applies, the CLR resolves DiagnosticSource 8.0.0.0, and the type initializer throws.
Impact: all on-premises upgrade automation on 28.5 is blocked — database conversion, and any other cmdlet that builds a NavEnvironment.
Expected behavior
Invoke-NAVApplicationDatabaseConversion (and other Management cmdlets creating a NavEnvironment) should run successfully from powershell.exe after importing NavAdminTool.ps1, exactly as they do on BC 28.3 and earlier.
Steps to reproduce
- Install Business Central 28.5 on-premises (build
28.0.54016.0) on Windows Server 2022, .NET Framework 4.8. - Open a clean
powershell.exe -NoProfilesession (Windows PowerShell 5.1, Desktop edition). - Import the admin tool:
. 'C:\Program Files\Microsoft Dynamics 365 Business Central\280\Service\NavAdminTool.ps1' - Run a database conversion against a database from an earlier version (e.g. 27.3):
Invoke-NAVApplicationDatabaseConversion ` -DatabaseServer 'SQLSERVER' ` -DatabaseName 'BC Test' ` -Force - The cmdlet fails with
TypeInitializationExceptionbefore touching SQL.
Repeating the same steps on BC 28.3 (28.0.52201.0) succeeds.
Additional context
Environment
- Windows Server 2022 Standard / Datacenter
- .NET Framework 4.8, release
528449 - Windows PowerShell 5.1 (Desktop) — reproduced on builds
5.1.20348.4294and confirmed working on5.1.20348.5499with 28.3 - Side-by-side BC installs present on both servers; ruled out as a factor (both machines have 5 versions installed,
PATH/PSModulePathcontain no BC entries, GAC contains noSystem.Diagnostics.DiagnosticSource)
Things that were ruled out
- Licence — the cmdlet fails before licence validation
- GAC pollution — no
DiagnosticSourcein GAC on either machine PATH/PSModulePath— no BC paths present- Az / AzureRM modules — not installed
- Preloading the correct assembly via
Assembly.LoadFromplus anAppDomain.AssemblyResolvehook does not help, because the OpenTelemetry reference is resolved in the default load context, which does not see the LoadFrom context
Workarounds
- Copy the
<assemblyBinding>section fromMicrosoft.Dynamics.Nav.Management.dll.configinto%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe.config, then run the cmdlet with the working directory set to...\280\Service. This is global and affects every PowerShell session on the machine, so it must be reverted afterwards. - Downgrade the platform to 28.3.
- Perform the upgrade inside a Docker container built from a 28.3 artifact.
Suggested fix
Any of the following would resolve it:
- Ship a
powershell.exe.configfragment (or documented merge step) together with the Administration Tool component - Apply the binding redirects programmatically from
NavAdminTool.ps1, e.g. via a dedicatedAppDomainwith the correctAppDomainSetup.ConfigurationFile - Pin
OpenTelemetry.Instrumentation.Httpto a version compatible with the shippedSystem.Diagnostics.DiagnosticSource 10.0.0.0, or ship a matchingDiagnosticSourceassembly version - Make
NavEnvironmenttolerate OpenTelemetry initialisation failures instead of propagating them as a fatalTypeInitializationException
I will provide a fix for a bug
- I will provide a fix for a bug
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing Invoke-NAVApplicationDatabaseConversion from a clean Windows PowerShell session after importing Service\NavAdminTool.ps1. Read Service\Management\Microsoft.Dynamics.Nav.Management.dll.config and Service\Microsoft.Dynamics.Nav.Server.exe.config, then compare how powershell.exe loads their binding redirects. Done means the conversion and other cmdlets that construct NavEnvironment run on 28.5 without a global PowerShell configuration workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- powershell
- Domain
- backend, cli
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100