# Azure Function App Deprecated Runtime Version

> Function Apps running a runtime past Microsoft's end-of-support get no security patches. Rule RC-1313 parses the discoverer's runtime value and fires when the version sits below the documented floor: Python 3.10, Node 22, Java 8, .NET 8, PowerShell 7.4. Ambiguous shapes like the Windows dotnet4.0 fallback always abstain.

Source: https://zop.dev/integrations/azure/recommendations/azure-function-app-deprecated-runtime-version
Updated: 2026-08-19

---

## Runtimes past their patch window

A function on a retired runtime keeps executing (Azure does not switch it off), but every
CVE published against that language version from retirement day onward stays unfixed
underneath your code. The exposure compounds silently: the app that was compliant when
deployed becomes a known-vulnerable surface without a single code change, and platform
support for it ends too. Severity is high because the risk grows with time, not with any
action you take.

## Pipe shape versus fallback shape

The only signal available is the discoverer's `runtime` metadata, taken from the site's ARM
FxVersion and written as a lowercased pipe pair: `python|3.12`, `node|20`,
`dotnetcore|8.0`. Only this shape names a real worker stack, so only this shape is judged.
The second shape, a pipe-less `dotnet4.0`-style string, comes from the `netFrameworkVersion`
fallback, a property that reads `v4.0` on *every* Windows site, whatever actually runs
there. A Node or PowerShell in-process app looks identical to a .NET Framework one under that
fallback, so the rule treats the shape as unknown-worker and abstains, a hardening added
after a live false positive.

## The support floors enforced

Each stack family has a minimum currently-supported version, sourced from Microsoft's
supported-languages page (last reconciled 2026-07-02): Python 3.10, Node 22, Java 8, .NET 8,
PowerShell 7.4. A parsed version below its family's floor fires; at or above it, the rule
abstains. Unrecognized stacks (`custom`, `docker`, anything without a floor entry) also
abstain rather than being guessed at. These floors roll forward as Microsoft retires
versions, so a finding today can be preceded by silence last quarter on the same app.

## Sequencing an upgrade

Runtime upgrades are app-setting changes, but rarely *only* that: Node major bumps and Python
minors both surface dependency breakage, and the .NET path usually means moving to the
isolated worker model. Upgrade a staging slot first, run the function's actual triggers
against it, then swap. The slot mechanism exists for precisely this. Check the current
value under the Function App's Environment variables blade before and after.

## List runtime stacks across function apps

```bash
az functionapp config show -n <app> -g <rg> \
  --query "{linux: linuxFxVersion, windows: windowsFxVersion, netFx: netFrameworkVersion}"
```

Compare the reported stack and version against the floors above; a bare `netFx` value with
both FxVersions empty is the ambiguous Windows case the rule declines to judge.
