You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Flex Consumption: ARM accepts uncatalogued functionAppConfig.runtime.version (e.g. "10" instead of "10.0"); app then fails only at host startup with generic InternalServerError #2666
Creating a Flex Consumption function app with a functionAppConfig.runtime.version value that is not in the regional runtime catalog (e.g. "10" where the catalog value is "10.0" for dotnet-isolated) succeeds at ARM PUT time with no error or warning. The resulting app is permanently broken in the most opaque way possible:
every instance start fails; the app URL never responds (connection timeout),
POST .../host/default/listkeys returns 400 BadRequest: "Encountered an error (InternalServerError) from host runtime.",
zip deployments upload successfully but end with "Function triggers synchronization failed due to Response status code does not indicate success: 500 (Internal Server Error)",
nothing anywhere: portal, ARM, deployment logs; points at the runtime version.
Diagnosing this took a full team-day, because every symptom points at deployment, storage, RBAC, or app code instead at the one-character config difference.
Repro
Reproduces with any client that passes the raw string through to ARM (Bicep, ARM template, Terraform azurerm/azapi, az resource create). Note az functionapp create does NOT repro; the CLI validates and normalizes client-side (see "Evidence" below).
Create a Flex Consumption app (Bicep or az resource) with:
in a region where the catalog value is "10.0" (e.g. West Europe; verify with az functionapp list-flexconsumption-runtimes --location westeurope --runtime dotnet-isolated).
Observe: creation succeeds. Portal shows a healthy-looking app.
az rest --method post --url ".../sites/<app>/host/default/listkeys?api-version=2023-12-01" -> 400 BadRequest / "Encountered an error (InternalServerError) from host runtime."
Patch the resource: runtime.version -> "10.0". Redeploy. Everything works immediately. No other change.
Expected behavior
Any one of:
Reject at PUT with a 400 naming the property and the valid values. The RP demonstrably already does this for some invalid versions: creating with python "V2" returns "Site.FunctionAppConfig.Runtime.Version is invalid. The specified value of runtime version 'V2' for runtime name 'python' is not supported." (quoted in function_app_flex_consumption - Update allowed python versions hashicorp/terraform-provider-azurerm#31154). So a validation allow-list exists; bare-major dotnet values ("10") fall through a hole in it.
Normalize bare-major versions to the catalog form ("10" → "10.0"), which is exactly what azure-cli does client-side (_FlexFunctionAppStackRuntimeHelper in appservice/custom.py fetches the regional functionAppStacks?sku=FC1 catalog, matches version variants, and substitutes the canonical string into the request).
Fail specifically at provision time. If the value is accepted, the host/platform knows at instance start that it cannot resolve a worker image for dotnet-isolated|10; surfacing that (instead of a generic InternalServerError from host runtime through three different APIs) would make the failure self-explanatory.
Additional evidence the current contract is a trap
The Microsoft.Web swagger (CommonDefinitions.json, stable/2024-04-01 and 2024-11-01) types FunctionsRuntime.version as an unconstrained nullable string whose own description is "Function app runtime version. Example: 8 (for dotnet-isolated)"; i.e. the spec's own example uses the bare-major format that bricks the app (catalog value is 8.0).
The official Flex Bicep sample (Azure-Samples/azure-functions-flex-consumption-samples, IaC/bicep/main.bicep) constrains runtime.name with @allowed(...) but leaves the version a free string.
Terraform azurerm_function_app_flex_consumption validates runtime_name (StringInSlice) but runtime_version only as non-empty, so IaC users pass the raw string to ARM.
ARM/Bicep template reference documents runtime.name as an enum but version as a free string.
Summary
Creating a Flex Consumption function app with a
functionAppConfig.runtime.versionvalue that is not in the regional runtime catalog (e.g."10"where the catalog value is"10.0"fordotnet-isolated) succeeds at ARM PUT time with no error or warning. The resulting app is permanently broken in the most opaque way possible:POST .../host/default/listkeysreturns400 BadRequest:"Encountered an error (InternalServerError) from host runtime.","Function triggers synchronization failed due to Response status code does not indicate success: 500 (Internal Server Error)",Diagnosing this took a full team-day, because every symptom points at deployment, storage, RBAC, or app code instead at the one-character config difference.
Repro
Reproduces with any client that passes the raw string through to ARM (Bicep, ARM template, Terraform azurerm/azapi,
az resource create). Noteaz functionapp createdoes NOT repro; the CLI validates and normalizes client-side (see "Evidence" below).az resource) with:"10.0"(e.g. West Europe; verify withaz functionapp list-flexconsumption-runtimes --location westeurope --runtime dotnet-isolated).status: 6,"Function triggers synchronization failed ... 500".az rest --method post --url ".../sites/<app>/host/default/listkeys?api-version=2023-12-01"->400 BadRequest / "Encountered an error (InternalServerError) from host runtime."runtime.version->"10.0". Redeploy. Everything works immediately. No other change.Expected behavior
Any one of:
"V2"returns"Site.FunctionAppConfig.Runtime.Version is invalid. The specified value of runtime version 'V2' for runtime name 'python' is not supported."(quoted in function_app_flex_consumption - Update allowed python versions hashicorp/terraform-provider-azurerm#31154). So a validation allow-list exists; bare-major dotnet values ("10") fall through a hole in it."10"→"10.0"), which is exactly what azure-cli does client-side (_FlexFunctionAppStackRuntimeHelperinappservice/custom.pyfetches the regionalfunctionAppStacks?sku=FC1catalog, matches version variants, and substitutes the canonical string into the request).dotnet-isolated|10; surfacing that (instead of a genericInternalServerError from host runtimethrough three different APIs) would make the failure self-explanatory.Additional evidence the current contract is a trap
CommonDefinitions.json, stable/2024-04-01 and 2024-11-01) typesFunctionsRuntime.versionas an unconstrained nullable string whose own description is "Function app runtime version. Example: 8 (for dotnet-isolated)"; i.e. the spec's own example uses the bare-major format that bricks the app (catalog value is8.0).Azure-Samples/azure-functions-flex-consumption-samples,IaC/bicep/main.bicep) constrainsruntime.namewith@allowed(...)but leaves the version a free string.azurerm_function_app_flex_consumptionvalidatesruntime_name(StringInSlice) butruntime_versiononly as non-empty, so IaC users pass the raw string to ARM.runtime.nameas an enum butversionas a free string.Related (not duplicates)
functionAppConfig.deployment.storage; redirected to the App Service RP.linux-fx-versionaccepts unsupported .NET 10).Environment
dotnet-isolated; catalog value"10.0", accepted invalid value"10".FC1), Linux.