Azure Functions · Runbook
Azure Functions end of support: PowerShell 7.4, .NET 8 and 9
Learn lists 10 November 2026 as the expected end of support for PowerShell 7.4, .NET 8, .NET 9 and in-process Functions. Who is affected and how to move.
- Effort: 1-2 hours per app
- Risk: Medium
- Rollback: Yes
Applies to: Azure Functions
Microsoft Learn lists 10 November 2026 as the expected end-of-support date on Functions runtime v4.x for PowerShell 7.4, .NET 8 and .NET 9 (isolated worker), and for the in-process .NET model. Learn lists PowerShell 7.6 and .NET 10 as GA until 14 November 2028. Inventory your function apps, use a staging slot where the plan supports one, and move to the newer stack before the date. Apps on retired versions keep running, but Learn says they stop getting patches.
Checked on 16 October 2026. The dates come from the Microsoft Learn pages below. The Learn tables label the column “Expected end-of-support date”, so treat the dates as expected, not guaranteed. Confirm against the Learn pages and any email notifications from the Functions team about affected apps.
- Compare Azure Functions runtime versions
- Supported languages in Azure Functions
- Language stack support policy
- Update language versions
- Migrate C# apps from in-process to isolated worker model
- PowerShell developer reference for Azure Functions
- PowerShell support lifecycle
- Deployment slots
- Flex Consumption plan
- Target runtime versions
Learn gives dates, not your tenant’s position. Check the language and runtime version of every app in your own subscriptions, and watch for notification emails about affected apps.
What changed
Learn’s versions page and supported-languages page list the same expected end-of-support dates for runtime v4.x:
| Stack | Learn lists | Date |
|---|---|---|
| PowerShell 7.4 | GA, expected end of support | 10 November 2026 |
| PowerShell 7.6 | GA | 14 November 2028 |
| .NET 8 (isolated worker) | GA, expected end of support | 10 November 2026 |
| .NET 9 (isolated worker) | GA, expected end of support | 10 November 2026 |
| .NET 10 (isolated worker) | GA | 14 November 2028 |
| Node.js 22 | GA, expected end of support | 30 April 2027 |
| Node.js 24 | GA | 30 April 2028 |
Other points from Learn:
- In-process model: Learn says support for the in-process model ends on 10 November 2026. In-process supports only .NET 8, so those apps must migrate to the isolated worker model to reach a later .NET version.
- .NET 9 date moved: Learn says .NET 9 previously had an end-of-support date of 12 May 2026. It was extended because the .NET team moved STS releases to 24 months of support.
- PowerShell lifecycle page: it lists PowerShell 7.4 (LTS, .NET 8) as ending support on 10-Nov-2026. It also lists PowerShell 7.5 as ending on 10-Nov-2026, and PowerShell 7.6 (LTS, .NET 10) on 14-Nov-2028.
- How the date is set: the support policy page says support ends on the earlier of the community end-of-support date for the language and the end-of-support date for the underlying base OS.
- Linux Consumption v3 apps: the supported-languages page says function apps still on the end-of-life v3 runtime on Linux in a Consumption plan stop running after 30 September 2026. Those need to move to v4. Confirm in your own subscriptions where any such apps stand.
Who is affected
- Apps on PowerShell 7.4.
- C# apps on the isolated worker model with .NET 8 or .NET 9.
- C# apps on the in-process model. Learn says support for the in-process model ends on 10 November 2026. It also says in-process supports only .NET 8, so reaching a later .NET version means migrating to the isolated worker model.
- Apps on Node.js 22, on the later 30 April 2027 date.
- Linux Consumption apps. Learn says .NET 9, Node.js 22 and PowerShell 7.4 are the last versions supported on that plan, and that the plan retires on 30 September 2028. Microsoft points to Flex Consumption as the target.
This post covers only the stacks in Learn’s tables above. If you run other languages, check the supported-languages page for their dates.
Why it matters
Learn’s support policy page says apps on retired language versions continue to run and can still be deployed. They are not eligible for new features, security patches or performance optimisations. It also says Microsoft may limit scale-out for them, in some cases to 1 instance.
So the failure mode is quiet. Nothing falls over on the date. You carry unpatched runtimes and a possible scale limit, which is a poor thing to explain in an audit.
Some moves are also constrained by plan:
- PowerShell 7.6 needs .NET 10 under the hood (7.4 maps to .NET 8). Learn says 7.6 is available on all hosting plans except Linux Consumption. A Linux Consumption app must first migrate to Flex Consumption before moving from 7.4 to 7.6.
- Flex Consumption lists .NET 8, 9 and 10 (isolated worker only) and PowerShell 7.4 and 7.6, so Flex apps can move in place. Learn says there is no in-place migration from another plan to Flex: you create a new Flex app and redeploy.
- Flex Consumption does not support deployment slots (Learn says rolling updates are in public preview). It also does not support PowerShell managed dependencies, so modules must be uploaded with the app content.
Runbook
-
Inventory every function app
For each app, record the plan, the runtime version and the language version.
- Runtime version: in the portal, go to the function app > Settings > Configuration > Function runtime settings tab and read Runtime version (for example
~4). With Azure CLI,az functionapp config appsettings listshowsFUNCTIONS_EXTENSION_VERSION. In Azure PowerShell, useGet-AzFunctionAppSetting. - Language version: print
$PSVersionTablefrom any PowerShell function, or use theaz functionapp showquery below. - Linux apps: Learn says you can’t currently set
linuxFxVersionin the portal or by using Azure PowerShell, so pinning a runtime image throughlinuxFxVersionis Azure CLI only. Learn givesaz functionapp config show --query linuxFxVersionto view it. For changing the language version, see the version-change step below. Learn says Linux Consumption apps can’t be updated in the portal.
Script
az functionapp showacross your subscriptions, or use your own inventory tooling, and test it before relying on it. - Runtime version: in the portal, go to the function app > Settings > Configuration > Function runtime settings tab and read Runtime version (for example
-
Sort apps by plan and path
- Linux Consumption on PowerShell 7.4: plan a move to Flex Consumption first. That is a new app and a redeploy.
- Flex Consumption: no slots. Use a non-production app or rolling updates (public preview) to test.
- In-process .NET: this is a migration project. Schedule it separately.
- Everything else: a version change on a staging slot.
-
Prepare and test locally
Learn says to review extension bundles (
host.jsonshould reference a compatible v4 bundle), binding extensions and package dependencies, then test locally on the target version. For .NET, update theTargetFrameworkand theMicrosoft.Azure.Functions.Workerpackages.For PowerShell, check your modules against 7.6 and .NET 10. If the app is on Flex, upload modules with the app content because managed dependencies are not supported.
-
Migrate in-process apps to the isolated worker model
The migration guide assumes the app already runs on runtime 4.x. It recommends targeting .NET 10, or .NET Framework 4.8 if the app needs .NET Framework-only libraries. The project changes it lists:
- Set the project SDK to
Azure.Functions.Sdk/1.0.0. - Set
TargetFrameworktonet10.0(ornet48). - Replace
Microsoft.NET.Sdk.FunctionswithMicrosoft.Azure.Functions.Workerpackages. - Replace
Microsoft.Azure.WebJobs.*packages with the Worker extension packages. - Add a
Program.csthat replacesFunctionsStartup. - Rename the
FunctionNameattribute toFunction. - Get
ILogger<T>by dependency injection.
Locally, set
FUNCTIONS_WORKER_RUNTIMEtodotnet-isolatedinlocal.settings.json. In Azure, set the same app setting and publish the migrated project. Each change restarts the app, and in between Learn says the app shows the runtime/payload mismatch error AZFD0013. That is why Learn says to use a staging slot, not markFUNCTIONS_WORKER_RUNTIMEas a slot setting, and swap. - Set the project SDK to
-
Publish to a staging slot and change the stack version there
Learn’s recommended workflow is: publish the updated code to a staging slot, update the stack configuration on that slot, verify, then swap into production.
Before you swap, mark event-source and binding settings as slot (sticky) settings. Learn says slot swaps do not guarantee zero downtime, because running functions can be terminated. It also says swapping resets keys when
AzureWebJobsSecretStorageTypeisfiles.Slot counts by plan, from Learn: Consumption has 2 (production plus 1 staging), Premium 3, Dedicated 1-20. Flex Consumption has none.
-
Change the version
Pick the method that fits the plan:
- Portal (PowerShell): function app > Settings > Configuration > General settings > PowerShell version. The update-language-versions page calls it PowerShell Core Version. Save, then choose Continue at the restart warning.
- Azure CLI, Windows apps:
az functionapp config setwith--powershell-version, or--net-framework-version "v<VERSION>.0"for .NET. Add--slotto target a slot. - Azure CLI, Linux apps:
az functionapp config set --linux-fx-version "<LANGUAGE|VERSION>". Take supported values fromaz functionapp list-runtimes. - Azure PowerShell:
Set-AzResourceagainst the site config resource, as below.
Learn says Linux Consumption apps cannot be updated in the portal and points to Azure CLI for them.
Updating the stack version restarts the app. Learn says a directly updated production app is unavailable for a brief period, typically 30-60 seconds, and in-flight requests are terminated.
-
Verify, then swap
Check the version on the slot with the verification command below, run your smoke tests, then swap. Keep the swap reversible (see Rollback).
Commands from Learn
Set the PowerShell version on a slot with Azure CLI:
az functionapp config set --powershell-version "<VERSION>" --name "<FUNCTION_APP_NAME>" --resource-group "<RESOURCE_GROUP_NAME>" --slot "staging"Set it with Azure PowerShell through the site config resource:
Set-AzResource -ResourceId "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Web/sites/<FUNCTION_APP>/config/web" -Properties @{ powerShellVersion = '<VERSION>' } -Force -UsePatchSemanticsVerify the PowerShell version:
az functionapp show --name "<FUNCTION_APP_NAME>" --resource-group "<RESOURCE_GROUP_NAME>" --query "siteConfig.powerShellVersion" --output tsvFor .NET, Learn uses siteConfig.netFrameworkVersion in the same query. For Linux apps it uses siteConfig.linuxFxVersion.
Do not change FUNCTIONS_EXTENSION_VERSION on its own. Learn says ~4 means the app runs the latest minor version of the latest major version (4.x), and tells you to follow the migration guides for existing apps, not to change that setting. FUNCTIONS_WORKER_RUNTIME sets the language stack. Flex Consumption does not support FUNCTIONS_EXTENSION_VERSION, so a Flex app cannot pin a runtime version.
Checks
-
Every function app is in your inventory with plan, runtime version and language version recorded.
-
No app is left on PowerShell 7.4, .NET 8, .NET 9 or the in-process model without a recorded decision and owner.
-
Node.js 22 apps are on the list with the 30 April 2027 date from Learn.
-
Linux Consumption apps have a Flex Consumption migration plan.
-
The verification query returns the target version on the slot before you swap.
-
Event-source and binding settings are marked as slot settings before the swap.
-
Smoke tests pass after the swap, and logs show no AZFD0013 errors.
Rollback
- After a slot swap: Learn says to return to the preswapped state by doing another swap to reverse it.
- If you changed the version directly in production: set the previous version again and redeploy the previous code.
- Flex Consumption: there are no slots, so keep the previous app and its deployment package until the new one is proven.
- In-process migration: keep the old project and app settings in source control until the isolated version has been through a full release cycle.
Common pitfalls
- Changing
FUNCTIONS_EXTENSION_VERSIONand calling it done. It is the runtime, not the language stack. Follow the migration guides. - Assuming the date is a cliff. Learn says retired apps keep running. The cost is no patches and possible scale limits, so it is easy to put off.
- Using the old .NET 9 date. Learn says it was 12 May 2026 before the extension. The versions page lists 10 November 2026.
- Newtonsoft attributes in the isolated model. System.Text.Json is the default serialiser, and Learn says attributes such as
[JsonProperty]are silently ignored. - Synchronous HTTP stream I/O. With ASP.NET Core integration, Learn says it can throw
InvalidOperationException. - Output bindings without the
Outputsuffix. Learn givesQueueOutputas an example.host.jsonneeds no changes. - Marking
FUNCTIONS_WORKER_RUNTIMEas a slot setting. Learn says not to. - Planning a slot for Flex Consumption. Not supported. Plan a non-production app instead.
- Trying the PowerShell 7.6 move on Linux Consumption. Not available there. Move to Flex Consumption first.
- Treating the swap as zero downtime. Learn says it is not guaranteed.