You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
master (unreleased). Introduced by #1808, merged 2026-04-17 (0fc7bb25).
Released versions are not affected — 2.8.0 shipped 2026-04-06, before #1808, and does not list ExcelFinancialFunctions in any dependency group. This is a heads-up before the next release.
File Type
OTHER — build/packaging issue, not file-format specific
Issue Description
On net472, every financial function throws at runtime:
System.IO.FileLoadException : Could not load file or assembly
'ExcelFinancialFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
or one of its dependencies. A strongly-named assembly is required.
(Exception from HRESULT: 0x80131044)
main/NPOI.Core.csproj sets SignAssembly=true (../npoi.snk) and targets net472. #1808 added a PackageReference to ExcelFinancialFunctions 3.0.0, whose assembly is not strong-named (PublicKeyToken=null). .NET Framework forbids a strong-named assembly from binding to an unsigned dependency, so the load fails at runtime.
.NET Core / .NET 5+ dropped strong-name identity checks, which is why every net10.0 test assembly is green and only net472 fails.
This affects allnet472 consumers regardless of whether they sign their own assemblies — the failing link is NPOI.Core → ExcelFinancialFunctions, independent of the caller.
The reference has no PrivateAssets="all" Pack="false" (unlike the SkiaSharp entries alongside it), so it will flow into the published package as a real dependency for the .NETFramework4.7.2 group.
Reproduce Steps
Current CI already reproduces it — the windows-latest job on every master push fails with 34 net472 failures in NPOI.TestCases.dll, e.g. run 30535975609 (job 90849260174).
Equivalent minimal repro for a consumer: reference NPOI (built from master) from a net472 project and evaluate any financial formula, e.g. PMT(0.08/12, 20*12, 500).
Scope
Because CLR assembly loading is lazy, the failure only triggers when a financial function actually executes — ordinary formula evaluation on net472 is unaffected. The affected functions are the ones routed through the new engine:
Three things happened to combine, which may be worth addressing independently of the fix:
The compile-time warning was suppressed in the same commit.59d46e7a added <NoWarn>$(NoWarn);CS8002</NoWarn> to main/NPOI.Core.csproj in the same diff that added the package reference. CS8002 is "Referenced assembly does not have a strong name" — precisely this problem.
As an aside, #1808's last PR run failed on a different load error in the same netstandard2.0-on-net472 chain (System.Memory, Version=4.0.1.2). That was pinned in 52bc1204 and the PR merged; the strong-name failure only appeared post-merge, so no PR-level run ever displayed it.
Possible fixes
I don't have a strong opinion on which is right for the project, but the options seem to be:
Exclude the reference on net472 and keep NPOI's previous managed implementations for that TFM (Condition="'$(TargetFramework)' != 'net472'"), guarding the call sites.
Get a strong-named ExcelFinancialFunctions. Upstream is netstandard2.0-only and was last published 2021-12-07, so this looks unlikely without a fork. (Note the project already uses MathNet.Numerics.Signed rather than plain MathNet for the same reason.)
Drop SignAssembly for net472 — probably a non-starter, since it would break existing signed consumers.
Drop net472 from NPOI.Core's TargetFrameworks.
Whichever route, re-enabling CS8002 (or at least scoping the NoWarn narrowly) would prevent a recurrence, and making the windows-latest job's status visible at the run level would help the next case surface on the PR rather than after merge.
Filed by Claude (AI assistant) on behalf of @ken-swyfft. All run IDs, commit SHAs and package metadata above were verified against the GitHub and NuGet APIs; happy to provide the underlying log excerpts.
NPOI Version
master(unreleased). Introduced by #1808, merged 2026-04-17 (0fc7bb25).Released versions are not affected — 2.8.0 shipped 2026-04-06, before #1808, and does not list
ExcelFinancialFunctionsin any dependency group. This is a heads-up before the next release.File Type
Issue Description
On
net472, every financial function throws at runtime:main/NPOI.Core.csprojsetsSignAssembly=true(../npoi.snk) and targetsnet472. #1808 added aPackageReferencetoExcelFinancialFunctions3.0.0, whose assembly is not strong-named (PublicKeyToken=null). .NET Framework forbids a strong-named assembly from binding to an unsigned dependency, so the load fails at runtime..NET Core / .NET 5+ dropped strong-name identity checks, which is why every
net10.0test assembly is green and onlynet472fails.This affects all
net472consumers regardless of whether they sign their own assemblies — the failing link isNPOI.Core→ExcelFinancialFunctions, independent of the caller.The reference has no
PrivateAssets="all" Pack="false"(unlike theSkiaSharpentries alongside it), so it will flow into the published package as a real dependency for the.NETFramework4.7.2group.Reproduce Steps
Current CI already reproduces it — the
windows-latestjob on everymasterpush fails with 34net472failures inNPOI.TestCases.dll, e.g. run 30535975609 (job90849260174).Equivalent minimal repro for a consumer: reference NPOI (built from
master) from anet472project and evaluate any financial formula, e.g.PMT(0.08/12, 20*12, 500).Scope
Because CLR assembly loading is lazy, the failure only triggers when a financial function actually executes — ordinary formula evaluation on
net472is unaffected. The affected functions are the ones routed through the new engine:PV FV PMT NPER RATE IRR MIRR XIRR XNPV NPV IPMT PPMT CUMIPMT CUMPRINC DB DDB SLN SYD VDB EFFECT NOMINALWhy CI didn't flag it
Three things happened to combine, which may be worth addressing independently of the fix:
59d46e7aadded<NoWarn>$(NoWarn);CS8002</NoWarn>tomain/NPOI.Core.csprojin the same diff that added the package reference. CS8002 is "Referenced assembly does not have a strong name" — precisely this problem.masterpush (24581212794) both reportconclusion: success, while theirwindows-latestjobs areconclusion: failure. The red job never surfaced as a red check.windows-latestwas already red before Integrate ExcelFinancialFunctions as backing engine for NPOI financial formula evaluation #1808, so the 34 new failures blended into existing noise. Per-job status onmasterruns24281587961,24291664324,24484880085and24490962919(2026-04-11 → 04-16) iswindows-latest: failurein all four.As an aside, #1808's last PR run failed on a different load error in the same netstandard2.0-on-net472 chain (
System.Memory, Version=4.0.1.2). That was pinned in52bc1204and the PR merged; the strong-name failure only appeared post-merge, so no PR-level run ever displayed it.Possible fixes
I don't have a strong opinion on which is right for the project, but the options seem to be:
net472and keep NPOI's previous managed implementations for that TFM (Condition="'$(TargetFramework)' != 'net472'"), guarding the call sites.ExcelFinancialFunctions. Upstream is netstandard2.0-only and was last published 2021-12-07, so this looks unlikely without a fork. (Note the project already usesMathNet.Numerics.Signedrather than plain MathNet for the same reason.)SignAssemblyfornet472— probably a non-starter, since it would break existing signed consumers.net472fromNPOI.Core'sTargetFrameworks.Whichever route, re-enabling CS8002 (or at least scoping the
NoWarnnarrowly) would prevent a recurrence, and making thewindows-latestjob's status visible at the run level would help the next case surface on the PR rather than after merge.Filed by Claude (AI assistant) on behalf of @ken-swyfft. All run IDs, commit SHAs and package metadata above were verified against the GitHub and NuGet APIs; happy to provide the underlying log excerpts.