If you're developing Azure Functions using the .NET isolated worker model (.NET 8, .NET 9, or even preview .NET 10) on a Mac with Apple Silicon and you run func start, you've almost certainly seen this exact error:
[2026-02-22T20:18:22.336Z] Grpc.Core: Error loading native library. Not found in any of the possible locations:
/Users/.../bin/output/.azurefunctions/libgrpc_csharp_ext.arm64.dylib,
.../runtimes/osx-arm64/native/libgrpc_csharp_ext.arm64.dylib,
.../../../runtimes/osx-arm64/native/libgrpc_csharp_ext.arm64.dylib.
Value cannot be null. (Parameter 'provider')
Host startup operation has been canceled
This issue has existed since 2023 and, as of February 2026, is still not fixed in Azure Functions Core Tools (4.x) or the .NET worker. It affects every isolated-worker function on ARM64 Macs because the legacy Grpc.Core library (used internally by the Functions host-worker communication) never shipped official osx-arm64 binaries.
The good news? There's a battle-tested, 2-minute fix that works reliably in 2026.
Why This Happens
The Azure Functions runtime looks for libgrpc_csharp_ext.arm64.dylib in the .azurefunctions folder (and a few fallback paths).
Contrib.Grpc.Core.M1 is a tiny community package that ships the correctly compiled ARM64 .dylib.
An MSBuild target then copies it to the exact location the runtime expects.
Step-by-Step Fix (Works for Regular Functions + Durable Functions)
1. Add the NuGet Package
Open your main function project’s .csproj file (e.g. CenchatFileUpload.csproj) and add this inside any :
<PackageReference Include="Contrib.Grpc.Core.M1" Version="2.46.7" />
Note: 2.46.7 is the latest version (March 2024) and works great.
Microsoft’s official Durable Functions docs (updated May 2025) recommend pinning to 2.41.0 for extensions projects — you can use either, but 2.46.7 is fine for almost everyone.
If you have a separate extensions.csproj (common with Durable Functions or when using many Worker.Extensions.* packages), add the reference there too.
2. Add the MSBuild Copy Target
Still in the same .csproj file, add this after the (but still inside ):
<Target Name="CopyGrpcNativeAssetsToOutDir" AfterTargets="Build">
<ItemGroup>
<NativeAssetToCopy Condition="$([MSBuild]::IsOSPlatform('OSX'))"
Include="$(OutDir)runtimes/osx-arm64/native/*" />
</ItemGroup>
<Copy SourceFiles="@(NativeAssetToCopy)"
DestinationFolder="$(OutDir).azurefunctions/runtimes/osx-arm64/native" />
</Target>
This target runs automatically after every build and copies the .dylib into the hidden .azurefunctions folder that func start actually uses.
3. Clean + Rebuild
dotnet clean
dotnet build
4. Run the Function Host Bash
func start
You should now see the host start successfully without any gRPC errors.
Verification
After building, check that the file exists:
ls bin/Debug/net8.0/.azurefunctions/runtimes/osx-arm64/native/
# or wherever your OutDir points (e.g. bin/output/.azurefunctions/...)
Final Thoughts
This workaround has saved countless macOS .NET developers over the last three years. It’s clean, reproducible, and doesn’t require any runtime hacks.
Hopefully Microsoft will eventually ship native arm64 support for the legacy gRPC bits or fully migrate to Grpc.AspNetCore, but until that day comes, Contrib.Grpc.Core.M1 + the copy target is the gold standard.
Did this fix work for you? Drop a comment below with your Core Tools version, .NET version, and macOS version — happy to help troubleshoot any follow-up errors!
Top comments (0)