azureblog.co.uk
← cd ~/posts

Azure Functions in-process support ends on 10 November: find your apps and move them to the isolated worker model

Support for the in-process model for .NET function apps ends on 10 November 2026, the same day .NET 8 reaches end of servicing. Find every affected app across your subscriptions, get an action list for your setup, and move to the isolated worker model with a staging slot and no downtime.

AzureNEW6 min read✓ checked 19 Oct 2026Azure · What's new · Automation
On this page
  1. Are you affected?
  2. What affects you?
  3. In-process vs isolated
  4. The migration, step by step
  5. Deploy with no downtime
  6. Checklist

If you run C# Azure Functions, there's a date to put in the diary. Microsoft ends support for the in-process model for .NET function apps on Tuesday 10 November 2026. The replacement is the isolated worker model, where your code runs in its own process, separate from the Functions host.

In-process model support ends in

Countdown to 10 November (UTC). .NET 8 reaches end of servicing on the same day.

Microsoft's guidance only says support ends. It doesn't say apps stop running that day. But an unsupported app gets no fixes, and no help from Microsoft when something breaks. The migration is mostly mechanical, so three weeks is enough if you start now.

Are you affected?

One app setting tells you. Open the function app, go to Settings › Environment variables and look at FUNCTIONS_WORKER_RUNTIME:

ValueWhat it means
dotnetIn-process. This app needs migrating.
dotnet-isolatedAlready on the isolated worker model. Check the .NET version below.
Anything elseNot a .NET app (Node, Python, PowerShell or Java). Not affected.

Find them all at once

Clicking through apps one by one doesn't scale. This loops through every subscription you can see and lists each function app with its worker runtime and .NET version. Run it in Cloud Shell or any session with the Az module, signed in with at least Reader on the subscriptions:

powershell21 lines
$results = foreach ($sub in Get-AzSubscription) {
    Set-AzContext -SubscriptionId $sub.Id | Out-Null
    Get-AzResource -ResourceType "Microsoft.Web/sites" |
        Where-Object Kind -like "*functionapp*" |
        ForEach-Object {
            $site = Get-AzWebApp -ResourceGroupName $_.ResourceGroupName -Name $_.Name
            $runtime = ($site.SiteConfig.AppSettings | Where-Object Name -eq "FUNCTIONS_WORKER_RUNTIME").Value
            [pscustomobject]@{
                Subscription = $sub.Name
                App          = $_.Name
                Runtime      = $runtime
                NetVersion   = if ($site.SiteConfig.LinuxFxVersion) { $site.SiteConfig.LinuxFxVersion } else { $site.SiteConfig.NetFrameworkVersion }
                Action       = switch ($runtime) {
                    "dotnet"          { "Migrate to isolated" }
                    "dotnet-isolated" { "Check .NET version" }
                    default           { "Not affected" }
                }
            }
        }
}
$results | Sort-Object Action, App | Format-Table -AutoSize

Reading app settings needs a role that can list them, such as Website Contributor, so with Reader only you'll see the apps but not the runtime column. Export the list with $results | Export-Csv functions.csv and you've got your migration tracker.

What affects you?

Tick what applies to your apps and you'll get an action list you can copy into a ticket.

In-process vs isolated

In-process
  • Runs inside the Functions host process
  • Tied to the host's .NET version
  • Uses Microsoft.Azure.WebJobs packages and [FunctionName]
  • Support ends 10 November 2026
Isolated worker
  • Runs in its own process, separate from the host
  • Choose your .NET version, including .NET 10 and .NET Framework 4.8
  • Normal .NET startup with Program.cs, dependency injection and middleware
  • Microsoft's supported model from now on
The two .NET hosting models for Azure Functions.

The migration, step by step

Microsoft recommends the .NET Upgrade Assistant, which makes many of the project changes for you. It's still worth knowing what changes, so you can review what it did.

1. Update the project file

Change the target framework to net10.0 and remove the Microsoft.NET.Sdk.Functions package. Add the isolated worker packages in its place:

xml9 lines
<TargetFramework>net10.0</TargetFramework>

<ItemGroup>
  <FrameworkReference Include="Microsoft.AspNetCore.App" />
  <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.52.0" />
  <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.1.0" />
  <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
  <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>

Microsoft's guide has the full project file, including the new SDK line. Check it for the current package versions when you migrate.

2. Swap the binding packages

Every Microsoft.Azure.WebJobs.Extensions.* package has an isolated equivalent under Microsoft.Azure.Functions.Worker.Extensions.*. For example, the Service Bus extension becomes Microsoft.Azure.Functions.Worker.Extensions.ServiceBus. Timer triggers need Microsoft.Azure.Functions.Worker.Extensions.Timer. When you're done, the project mustn't reference any Microsoft.Azure.WebJobs.* package.

3. Add Program.cs

The isolated model starts like any other .NET app. This file replaces any FunctionsStartup class you had, so move your service registrations into it:

text14 lines
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

If the app has no HTTP triggers, you can use ConfigureFunctionsWorkerDefaults() instead.

4. Update the functions

Here's a queue-triggered function for a contoso order system that writes a receipt to blob storage. Before, in-process:

text15 lines
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

public static class ProcessOrder
{
    [FunctionName("ProcessOrder")]
    public static void Run(
        [QueueTrigger("orders", Connection = "ContosoStorage")] string order,
        [Blob("receipts/{rand-guid}.json", FileAccess.Write, Connection = "ContosoStorage")] out string receipt,
        ILogger log)
    {
        log.LogInformation("Processing order {Order}", order);
        receipt = order;
    }
}

After, isolated worker:

text13 lines
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class ProcessOrder(ILogger<ProcessOrder> logger)
{
    [Function("ProcessOrder")]
    [BlobOutput("receipts/{rand-guid}.json", Connection = "ContosoStorage")]
    public string Run([QueueTrigger("orders", Connection = "ContosoStorage")] string order)
    {
        logger.LogInformation("Processing order {Order}", order);
        return order;
    }
}

What changed:

  • [FunctionName] becomes [Function], and the namespace moves from Microsoft.Azure.WebJobs to Microsoft.Azure.Functions.Worker.
  • The logger is injected through the constructor as ILogger<T>, not passed in as a parameter.
  • Triggers keep their names. Input bindings gain Input and output bindings gain Output, so [Blob] for writing becomes [BlobOutput].
  • Output bindings move to the return value. If a function has several outputs, return a class with one property per output.
  • IAsyncCollector<T> becomes an array return such as T[], and IBinder parameters go.

5. Watch the two easy-to-miss changes

  • JSON serialisation. The isolated model uses System.Text.Json by default. It ignores Newtonsoft attributes like [JsonProperty] and [JsonIgnore] without any error, so property names quietly change in your output. Test any function that returns or stores JSON.
  • Logging levels. host.json now only controls the host's own logs. Set log filtering for your code in Program.cs, or you may get far more (or fewer) logs in Application Insights than before.

6. Update local settings

In local.settings.json, set "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" and run the app locally before going anywhere near Azure.

Deploy with no downtime

The code and the FUNCTIONS_WORKER_RUNTIME setting have to change together. Change the setting first and the app throws error AZFD0013, a mismatch between the setting and the code, until the new code arrives. A staging slot avoids that:

shell9 lines
# 1. Point the staging slot at the isolated worker (not as a slot setting)
az functionapp config appsettings set -g rg-contoso-orders -n func-contoso-orders --slot staging `
    --settings FUNCTIONS_WORKER_RUNTIME=dotnet-isolated

# 2. Publish the migrated code to the staging slot and test it

# 3. Swap staging into production
az functionapp deployment slot swap -g rg-contoso-orders -n func-contoso-orders `
    --slot staging --target-slot production

Don't tick Deployment slot setting on FUNCTIONS_WORKER_RUNTIME. It needs to travel with the code during the swap, so production gets the new setting and the new code as one change. Set the app's .NET version to 10 in the slot's configuration too. On plans without slots, deploy the code and the setting together in one pipeline run, and pick a quiet time.

Checklist

  • Every function app listed with its worker runtime and .NET version
  • In-process apps moved to the isolated worker model on .NET 10
  • Isolated apps on .NET 8 moved to .NET 10
  • No Microsoft.Azure.WebJobs.* packages left in any project
  • JSON output tested where models use Newtonsoft attributes
  • Log filtering set in Program.cs and checked in Application Insights
  • Pipelines updated to build for the new framework and keep dotnet-isolated
  • Production swapped from a tested staging slot
Will my in-process apps stop working on 10 November?

Microsoft's guidance says support ends on that date. It doesn't say apps stop running. But they'll get no fixes and no support, so treat 10 November as the deadline.

Which .NET version should I target?

Microsoft recommends .NET 10 for most apps. If your code depends on APIs that only exist in .NET Framework, target .NET Framework 4.8 on the isolated worker model.

My app is already isolated. Am I done?

Only if it's on .NET 10. .NET 8 reaches end of servicing on 10 November 2026 as well, so isolated apps on .NET 8 need retargeting.

What does error AZFD0013 mean?

The FUNCTIONS_WORKER_RUNTIME setting doesn't match the deployed code, usually because the setting was changed before the migrated code was published. Deploy the code and the setting together, ideally through a staging slot.