Blog Post

Azure Integration Services Blog
13 MIN READ

Migrate NuGet-based Logic Apps Standard apps and custom built-in connectors to .NET 10

WSilveira's avatar
WSilveira
Icon for Microsoft rankMicrosoft
Nov 13, 2026

You built a custom built-in connector for Logic Apps Standard and your NuGet-based Logic Apps project pulls it in at build time. You want to know what it takes to move that stack to .NET 10.

Less than you might fear. You don't change a line of C#, and you don't touch your workflow definitions. The work is retargeting your projects, resolving a couple of dependency conflicts, running the right host locally, and changing a handful of app settings in Azure. Those last two are where people get stuck, so I spend most of this post on them.

This is a companion to Logic Apps Standard custom code now supports .NET 10. That post covers custom-code (local function) projects. This one covers NuGet-based applications and the custom built-in connectors they consume, and it answers the questions you left in the comments on the custom code post. We validated every step below end to end, locally and in Azure, with a NuGet-based sample app and a custom built-in connector.

Which post do you need?

Your Logic Apps Standard appWhat to do
Workflows only, bundle-basedNo project changes. The platform moves the app to the out-of-proc host.
Workflows plus a custom-code (local function) projectFollow the custom code .NET 10 post.
NuGet-based project, with or without custom built-in connectorsFollow this post.
NuGet-based project that also has a custom-code projectUse this post for the app and connectors, and the custom code post for the function project. 

Your code stays the same

Your code don't change. Keep the [assembly: WebJobsStartup] attribute, your IWebJobsStartup.Configure method and your IServiceOperationsProvider implementation exactly as they are. Your workflow definitions don't change either. You don't add an isolated worker project or a Program.cs file.

We validated this with a sample custom built-in connector that exposes an action, locally and in Azure. That tells you the model works. It doesn't tell you your connector works. Your connectors and their dependencies still need application-specific testing, and I come back to that in the limitations section.

First, understand which host runs your app

A connector built for net10.0 needs a .NET 10 host. The .NET 8 host can't load it: every type fails with a missing System.Runtime 10.0.0.0 reference. So the whole migration comes down to two things: building for net10.0, and making sure a .NET 10 host runs the result.

Azure and your local tools choose that host in different ways, and this is the part that catches people out:

WhereFUNCTIONS_WORKER_RUNTIMEWhat selects the .NET 10 host
Azuredotnet (unchanged)Removing LOGICAPP_INPROC_REDIRECT. Without it, the platform runs your app on the out-of-proc host on .NET 10.
Local (Azure Functions Core Tools)dotnet-isolatedCore Tools ignores LOGICAPP_INPROC_REDIRECT. With dotnet it always picks its .NET 8 in-process host. With dotnet-isolated, Core Tools 4.16.0 or later uses its main host, which runs on .NET 10. 

dotnet-isolated doesn't move you to the isolated worker model. The Workflows runtime and your connector still load into the host process; the value only changes which host Core Tools starts. That's also why it's a local-only value. Keep it out of your Azure app settings and deployment templates. This is a current limitation of the the extension and we are working to remove this extra configuration step.

Check your prerequisites

  • The .NET 10 SDK, version 10.0.403 or later. The Azure Logic Apps (Standard) extension for VS Code, version 5.1013.4, installs it in the extension's managed dependencies folder. On Windows the default is %USERPROFILE%\.azurelogicapps\dependencies\DotNetSDK.
  • Azure Functions Core Tools 4.16.0 or later, the first version whose main host runs on .NET 10. The extension installs a managed copy in %USERPROFILE%\.azurelogicapps\dependencies\FuncCoreTools. An older copy installed through npm and earlier on your PATH (4.12.0 in our testing) runs on .NET 8 and fails to start the app.
  • Microsoft.Azure.Workflows.WebJobs.Extension 1.170.91 or later. The current version at the time of this post on NuGet is 1.194.31, which is the version we validated. Use the latest version you have available as it will have the latest product improvements and fixes.
  • Microsoft.NET.Sdk.Functions 4.5.0 or later. We validated 4.5.0 and 4.6.0.
  • Write access to the package feed where you publish your connector packages.
  • A build agent image with the .NET 10 SDK for your pipeline.

Keep your current deployment stable while you migrate

If your app runs on .NET 8 today, leave its app settings alone until your .NET 10 build is validated and ready to deploy. Retaining the existing app settings preserves the current compatibility configuration while you prepare and validate the migration. For NuGet-based apps, that includes LOGICAPP_INPROC_REDIRECT=1, the setting that keeps your app on the legacy .NET 8 in-proc host. Remove it early and the app moves to the new host on its next restart, before your .NET 10 build is in place.

Check your pipelines too. A release that rebuilds app settings from a template can drop the redirect without anyone noticing.

Don't treat this as a reason to wait. .NET 8 apps keep running after end of support, but they no longer receive security fixes. Plan the migration now.

Update your project files

Work on a branch, and back up any local configuration before you start. This table lists every file that changed in our validated migration. Repeat the connector changes for every connector project your app consumes.

FileChange
global.json (repository root and Logic Apps project folder)Set the SDK version to 10.0.403 or later, with rollForward set to latestPatch. A leftover 8.0 pin fails the build with NETSDK1045.
Connector .csprojSet TargetFramework to net10.0. Reference Microsoft.Azure.Workflows.WebJobs.Extension 1.194.31. Add direct references for any NU1605 downgrades restore reports. Increment the package version (2.0.0 in our sample) so you can tell which connector loaded.
Connector startup and provider classesNo change.
Connector test projectsSet TargetFramework to net10.0.
Logic Apps .csprojSet TargetFramework to net10.0. Reference Microsoft.NET.Sdk.Functions 4.5.0 or later, Microsoft.Azure.Workflows.WebJobs.Extension 1.194.31 and your new connector package version. Keep the targets that copy the lib folder and your artifacts into the publish output.
host.jsonRemove any extensionBundle section. Keep version 2.0 and your existing logging and settings.
local.settings.jsonSet FUNCTIONS_WORKER_RUNTIME to dotnet-isolated.
.vscode/settings.jsonPoint deploySubpath at bin\Release\net10.0\publish.
.vscode/tasks.jsonSet the cwd of the func host start task to bin\Debug\net10.0, in every operating system block.
Build and deployment scriptsReplace net8.0 output paths with net10.0.

Pin the SDK

Update global.json in the repository root and in the Logic Apps project folder:

{
  "sdk": {
    "version": "10.0.403",
    "rollForward": "latestPatch"
  }
}

Retarget the connector and resolve downgrades

Restore is where the first failure shows up. In our sample, retargeting the connector with Workflows 1.194.31 produced NU1605 package downgrade errors, and two direct references fixed them:

  
    net10.0
    true
    Contoso.LogicApps.Connectors.Inventory
    2.0.0
  
  
    
    
    
    
  

Those were the right pins for our connector's dependency graph. Yours may need different ones, so read the NU1605 output and pin what it names rather than copying ours. If restore also reports vulnerability warnings, review them; don't suppress them as part of the migration.

Then build, pack, and publish the new version to your feed:

dotnet build -c Release
dotnet pack -c Release -o ./nupkg
dotnet nuget push ./nupkg/Contoso.LogicApps.Connectors.Inventory.2.0.0.nupkg --source 

If your Logic Apps project references the connector as a project reference rather than a package, skip the pack and push. The retarget and the dependency fixes still apply.

Retarget the Logic Apps project

The relevant parts of the project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.5.0" />
    <PackageReference Include="Microsoft.Azure.Workflows.WebJobs.Extension" Version="1.194.31" />
    <PackageReference Include="Contoso.LogicApps.Connectors.Inventory" Version="2.0.0" />
  </ItemGroup>
  <!-- Keep your existing None/Update items and CopyDynamicLibraries target. -->
</Project>

Don't remove Microsoft.NET.Sdk.Functions. It generates bin\extensions.json, which registers your connector with the host. Without it, the connector is missing from the build output.

A NuGet-based app loads the Workflows runtime from your package, not from an extension bundle, so host.json needs no bundle:

{
  "version": "2.0"
}

Version 5.1013.4 of the extension have a configuration bug. It is ignoring the following extension configuration set:

"azureLogicAppsStandard.enableProjectConsistencyChecks": false

With that your host.json file will include the extension bundle setting again when the project opens:

  "extensionBundle": {
  "id": "Microsoft.Azure.Functions.ExtensionBundle.Workflows",
  "version": "[1.*, 2.0.0)"
  }

Remove it before pushing to source control or running the application. We are working on a fix for this issue which will ship with the next version of the bundle.

Why a net8.0 package works in a net10.0 project

Microsoft.Azure.Workflows.WebJobs.Extension targets net8.0. That doesn't stop a net10.0 project from referencing it: NuGet treats net10.0 as compatible and selects the package's net8.0 assets. What has to be .NET 10 is the host that runs your app.

There's one side effect worth knowing about. On net10.0, the SDK resolves the package's ASP.NET Core framework reference to version 10, which already contains Microsoft.Extensions.DependencyInjection and related assemblies, so the build leaves the package copies out of your output. That's expected. The .NET 10 host supplies them, which is one more reason the app only runs on that host.

Run and verify locally

Set the worker runtime in local.settings.json and keep your other values as they are:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
  }
}
  • Make sure Core Tools 4.16.0 or later is the func that runs. If you start the host from a terminal or a script, check that the managed copy, not an older npm install, comes first on your PATH. The version banner tells you which one started.
  • Stop the host serving this project if it's running, then restore and build the Logic Apps project.
  • Start the host from bin\Debug\net10.0.
  • Check the host log. There should be no '/serviceProviders/' ... is not valid error, and your workflows should be listed.
  • Run a workflow for every operation you ship, triggers included, and check the run history.
  • Optionally, open a workflow in the designer, select Built-in, and confirm your connector's operations appear.

You may see Could not find the .azurefunctions folder in the deployed artifacts of a .NET isolated function app in the log. It's a warning that comes with the dotnet-isolated selection, and the workflows still run.

Update the Azure app settings

In Azure, the platform selects the .NET 10 host when LOGICAPP_INPROC_REDIRECT is absent, and FUNCTIONS_WORKER_RUNTIME stays dotnet. These are the settings we changed and the ones we left alone:

SettingAction
AzureFunctionsJobHost__extensionBundle__idDelete.
AzureFunctionsJobHost__extensionBundle__versionDelete. App settings override host.json, so removing the bundle from the file alone isn't enough.
LOGICAPP_INPROC_REDIRECTDelete if present. It forces the legacy .NET 8 host.
FUNCTIONS_WORKER_RUNTIMEKeep dotnet. dotnet-isolated is the local-only value.
FUNCTIONS_EXTENSION_VERSIONKeep ~4.
APP_KINDKeep workflowApp.
FUNCTIONS_INPROC_NET8_ENABLEDNot required. It's harmless if it's left over from .NET 8.
netFrameworkVersion (site configuration)No change. It stays v8.0 and doesn't decide which runtime loads.

The extension bundle settings are the easiest to miss. Apps created in the Azure portal usually get them by default. If either is present, the host loads the Workflows runtime from the bundle instead of your package, your connector never registers, and the log reports that '/serviceProviders/' is not valid. Your deployed package can be perfectly correct and still fail this way.

Keep your deployment template at dotnet as well, and make sure it doesn't add the bundle settings or the redirect back on the next release.

Deploy and verify in Azure

  1. Update your pipeline to build with the .NET 10 SDK, publish a Release build, and deploy the contents of bin\Release\net10.0\publish.
  2. Deploy to a non-production app or deployment slot first.
  3. For an existing app, stop it, change the app settings, deploy the .NET 10 package, and then start it. In that order, the new package never starts under the old configuration.
  4. Check the host log for the '/serviceProviders/' ... is not valid error. It shouldn't be there.
  5. Confirm that each workflow that uses your connector shows its callback URL, and that a test run succeeds.
  6. Optionally, open Process Explorer in Kudu and confirm the loaded modules: CoreCLR 10, your connector DLL at its new version, and the Workflows runtime at 1.194.31. That's the reliable way to see which runtime is running, because the settings don't tell you.
  7. Compare run history with the .NET 8 version, then promote the same build and the same settings to production.

A local settings file doesn't configure the Azure app. After each deployment, check the app settings on the deployed resource rather than trusting the template.

If you need to roll back, redeploy the .NET 8 package and restore LOGICAPP_INPROC_REDIRECT=1. Restoring the setting on its own isn't enough, because the .NET 8 host can't run a .NET 10 connector.

Symptoms and causes

If something fails, start here. These are the errors we hit during validation:

SymptomCause and fix
NETSDK1045: The current .NET SDK does not support targeting .NET 10.0A global.json pin or the selected SDK is still 8.0. Pin 10.0.403 or later.
NU1605 package downgrade errors on restoreTransitive dependency versions in your connector. Add direct references for the packages restore names.
Locally: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection, Version=9.0.0.0'FUNCTIONS_WORKER_RUNTIME is dotnet, so Core Tools started its .NET 8 in-process host. Set dotnet-isolated in local.settings.json.
Locally: Could not load file or assembly 'System.Text.Json, Version=9.0.0.0'An older Core Tools whose host runs on .NET 8 is first on your PATH. Use 4.16.0 or later.
'/serviceProviders/' ... is not valid, and no callback URLAn extension bundle is configured in host.json or in the AzureFunctionsJobHost__extensionBundle__* app settings. Remove both.
Connector and bin\extensions.json missing from the build outputMicrosoft.NET.Sdk.Functions was removed from the Logic Apps project. Add it back.

Use the migration skill

We've prepared the logicapps-nuget-connector-net10-migration skill to guide a coding agent through the same process. It inspects your solution, plans configuration changes before applying them, and guides build and test verification. It preserves your connector code and workflows rather than rewriting them, and it doesn't change Azure resources: it lists the app-setting changes for you to make.

The skill is available in the custom-connector-migration-net10 repository, with a working sample. The main branch holds the migrated .NET 10 version and the net8.0 branch holds the .NET 8 baseline, so you can try the skill on the sample before your own projects.

With GitHub CLI (command-line interface) version 2.90.0 or later, inspect the skill and install it for Copilot across projects. These skill commands are currently in preview.

gh skill preview wsilveiranz/custom-connector-migration-net10 logicapps-nuget-connector-net10-migration
gh skill install wsilveiranz/custom-connector-migration-net10 logicapps-nuget-connector-net10-migration --agent github-copilot --scope user

Installation makes the skill available to Copilot; it doesn't run the migration. After installation, you can ask your agent:

Migrate this NuGet-based Logic Apps Standard app and its custom built-in connector to .NET 10 using the logicapps-nuget-connector-net10-migration skill. Preserve my connector code and workflows, back up the projects first, and list the Azure app settings I need to change.

Note: we're submitting this skill to Awesome Copilot. When it's available there, we'll update this post with the new install commands.

Your questions, answered

Do I need to change how my custom built-in connector registers?

No. The existing registration model remains applicable: retain your IWebJobsStartup registration and IServiceOperationsProvider implementation. We validated a custom built-in connector with this model on the .NET 10 host, locally and in Azure. Your connectors and their dependencies still need application-specific testing.

Microsoft.Azure.Workflows.WebJobs.Extension targets net8.0. Can a net10.0 app reference it?

Yes. The package's net8.0 target doesn't prevent a net10.0 application from referencing it. A target framework isn't a requirement that the consuming application use exactly that framework. What does have to be .NET 10 is the host that runs your app. You still need to validate dependency compatibility, and restore tells you where to look.

I'm already on 1.194.31. Do I need to downgrade to 1.170.91?

No. 1.194.31 is newer than the 1.170.91 minimum in our migration guidance, and it's the version we validated. Stay where you are.

Do I need to move to the isolated worker model?

No. You don't add a worker project or a Program.cs file, and your connector still loads into the host process. dotnet-isolated is only the value that makes Core Tools start its .NET 10 host on your machine. In Azure, FUNCTIONS_WORKER_RUNTIME stays dotnet.

What should I do with my existing .NET 8 deployment in the meantime?

Keep its existing app settings. They preserve the current compatibility configuration while you prepare and validate the migration. Remove LOGICAPP_INPROC_REDIRECT when you deploy the .NET 10 package, not before.

When will the official documentation cover NuGet-based apps and custom built-in connectors?

We know you need explicit guidance for this scenario, and this post is that guidance today. We don't have a confirmed publication date for the Microsoft Learn update. Don't wait for it: migrate to .NET 10 at your earliest opportunity.

Before you migrate: what we haven't covered

  • We validated a sample connector with an action, not yours, and not a connector with triggers. Connectors that implement IServiceOperationsTriggerProvider, connectors with their own converters, and connectors with third-party libraries that pin older framework versions are where I'd expect surprises. Test every operation.
  • We haven't validated an app that combines a NuGet-based project with a custom-code project.
  • In our sample, the generateDebugSymbols prelaunch task in VS Code failed, because it looks up an extension bundle path and a NuGet-based project doesn't have one. Don't add a bundle to work around it; start the host from bin\Debug\net10.0 instead. We are working on a fix for this problem.
  • The Microsoft Learn article Create custom built-in connectors for Standard workflows still describes a .NET Core 3.1 class library project. Until it's updated, use this post as the reference for the target framework.
  • Don't pin your app to a specific extension bundle or Functions host version. Pinned apps needed manual updates during the out-of-proc migration, and they will again every time the platform moves.

Call to action

Retarget one connector this week and run it against a non-production app. If something fails, check the symptoms table first. If your error isn't there, post the connector shape (actions, triggers, converters), the package versions, and the error in the comments, without credentials or private data. I'll take the patterns back to the team and fold them into this post and the skill.

Updated Nov 13, 2026
Version 1.0
No CommentsBe the first to comment