Azure logo and Azure function logotype

Guide: Upgrade Azure Functions from .net6 to .net8 dotnet-isolated workers

This is a step-by-step developer's guide on how to upgrade your Azure Functions to .NET 8.

icon of user profile
By OMVP Luc Gosso

Table of Content

1. Migrate your .NET apps in Azure Functions to the isolated worker model by 10 November 2026
2. Benefits of the isolated worker model
3. Change to csproj
4. Remove Startup.cs File if you have one
5. Configure program.cs
6. Function attributes and logging with DI
7. local.settings.json file
8. Now you should be able to run it locally!
9. Upgrade your functions in Azure Portal
10. If the "Stack Settings" is missing
11. Related Error messages
a. CS5001 Program does not contain a static 'Main' method suitable for an entry point
b. The target framework 'net8.0' must be 'net6.0'. Verify if target framework has been overridden by a global property.

 

Migrate your .NET apps in Azure Functions to the isolated worker model by 10 November 2026

You may have received this email because you are utilizing the in-process model with .NET applications in Azure Functions.

Beginning 10 November 2026, the in-process model for .NET apps in Azure Functions will no longer be supported. To ensure that your apps that use this model continue being supported, you'll need to transition to the isolated worker model by that date.

You may still use your .NET apps with the in-process model beyond 10 November 2026, but they will no longer receive security and feature updates from Microsoft.

Benefits of the isolated worker model

There are two modes in which you can run your .NET class library functions: either in the same process as the Functions host runtime (in-process) or in an isolated worker process. When your .NET functions run in an isolated worker process, you can take advantage of the following benefits:

  • Fewer conflicts: Because your functions run in a separate process, assemblies used in your app don't conflict with different versions of the same assemblies used by the host process.
  • Full control of the process: You control the start-up of the app, which means that you can manage the configurations used and the middleware started.
  • Standard dependency injection: Because you have full control of the process, you can use current .NET behaviors for dependency injection and incorporating middleware into your function app.
  • .NET version flexibility: Running outside of the host process means that your functions can run on versions of .NET not natively supported by the Functions runtime, including the .NET Framework.

If you have an existing C# function app that runs in-process, you need to migrate your app to take advantage of these benefits. Follow this guide.

Change to csproj:

Change to:

<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Add to ItemGroup

    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />

Remove from Itemgroup 

    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.3.0" />

After your changes the csproj, should look something like this: 

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<RootNamespace>My.Namespace</RootNamespace>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.0" /><!-- beware of errors on publish with 1.17.1 and 2 -->
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
<!-- Other packages may also be in this list -->
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None>
<None Update="local.settings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>Never</CopyToPublishDirectory> </None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
</ItemGroup>
</Project>

Remove Startup.cs File if you have one

remove any [assembly: FunctionsStartup(typeof(Startup))] 

Configure program.cs

Add the following

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var host = new HostBuilder()

    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        // Register your services here
        //eg services.AddSingleton<IEpicweb, EpicwebService>();
    })
.ConfigureAppConfiguration((hostContext, config) => //This is for facilitating the logging functionality.

    {
        config.AddJsonFile("host.json", optional: true);
    })
    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddApplicationInsights(console =>
        {
            console.IncludeScopes = true;
        });

   logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
    }).ConfigureLogging(logging => //This is for facilitating the logging functionality in Application Insights.

// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override. // Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs


    {
        logging.Services.Configure<LoggerFilterOptions>(options =>
        {
            LoggerFilterRule defaultRule = options?.Rules?.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
            if (defaultRule is not null)
            {
                options.Rules.Remove(defaultRule);
            }
        });
    })
    .Build();

 

host.Run();

Function attributes and logging with DI

The FunctionName attribute is replaced by the Function attribute in the isolated worker model. The new attribute has the same signature, and the only difference is in the name. You can therefore just perform a string replacement across your project.

In the in-process model, you could include an additional ILogger parameter to your function, or you could use dependency injection to get an ILogger<T>. If you were already using dependency injection, the same mechanisms work in the isolated worker model.

using Epicweb.Azure.Function.Models;
using Epicweb.Azure.Function.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using System.Text.Json;

namespace Epicweb.Azure.Function
{
    public class Ping
    {
        private readonly ILogger<Ping> _logger;

        public Ping(ILogger<Ping> logger)
        {
            _logger = logger;
        }

        [Function("Ping")] //this is changed
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req) //no injection of logger in method anymore
        {
            var version = typeof(Ping)?.Assembly?.GetName()?.Version?.ToString(fieldCount: 4);
            var model = new PingModel() { Answer = "Pong", Version = version };
            HelperService.Log($"Ping trace {JsonSerializer.Serialize(model)}", _logger);
            return new JsonResult(model);
        }
    }
}

local.settings.json file

The local.settings.json file is only used when running locally. For information, see Local settings file.

When migrating from running in-process to running in an isolated worker process, you need to change the FUNCTIONS_WORKER_RUNTIME value to "dotnet-isolated". Make sure that your local.settings.json file has at least the following elements:

{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" }
}

Now you should be able to run it locally! 

Upgrade your functions in Azure Portal

Before you publish your code to the function app, you need to change the Stack Settings in the portal. Navigate to the Azure Function and Configuration.

If the "Stack Settings" is missing

You need to add it by including "dotnet-isolated" in the FUNCTIONS_WORKER_RUNTIME parameter on "Environment Variables" blade. This can be done in a deployment slot if used. Restart the app. Now the Stack settings should be visible.

 

YOU ARE GOOD TO GO!

Good luck! I hope this helps you save some time.

 

Related Error messages

CS5001 Program does not contain a static 'Main' method suitable for an entry point

This happens when you dont have any program.cs, see above solution

The target framework 'net8.0' must be 'net6.0'. Verify if target framework has been overridden by a global property.

This is a bug in version Microsoft.Azure.Functions.Worker.Sdk - 1.17.2
There will be no problem if you downgrade to version 1.17.1 or 0.

About the Author

Luc Gosso

OMVP Luc Gosso

– Independent Senior Web Developer
working with Azure and Optimizely