Azure / Azure/functions-action
Flex Consumption: every deploy fails with Kudu 'Site Unavailable (CODE: 503)'; identical Flex app in same subscription deploys fine
- Dominant language
- TypeScript
- Stars
- 184
- Forks
- 92
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
Flex Consumption function app: **every** deployment fails with `Site Unavailable (CODE: 503)` from `azure-app-kudu-service.js`. An identically-configured Flex app in the same subscription deploys the same package successfully.
The app itself is healthy throughout — `/api/health` returns 200 and timer triggers fire on schedule *during* the failed deploy window. Only deployment fails.
### Repro
```
Will use Kudu https:///api/publish ... t+0s
Will use parameter remote-build: true t+89s <-- 1s on the working app
oneDeploy : Failed to use .zip as OneDeploy content
Site Unavailable (CODE: 503)
at Kudu. (azure-app-kudu-service.js:274:41)
```
Reproduces on every run since 2026-08-19. **It also reproduces outside this action entirely** — `az functionapp deployment source config-zip` from an operator workstation returns the same 503, using SCM basic auth rather than the action's OIDC/RBAC. So it is not the action, the runner, the network, or the credential type.
### What we have eliminated (all measured, not assumed)
| | |
|---|---|
| The package | The identical zip deployed successfully to the sibling Flex app minutes earlier |
| The command | Same command, same package, succeeded on the sibling |
| The client | Fails from GitHub Actions **and** from a workstation |
| The auth path | Fails under OIDC/RBAC **and** under SCM basic auth |
| `DEPLOYMENT_STORAGE_CONNECTION_STRING` | Present; all 30 app settings intact |
| `functionAppConfig.deployment.storage` | `blobContainer` + `StorageAccountConnectionString`, byte-equivalent to the working app |
| The shared key itself | A hand-signed `SharedKey` request to `GET /app-package?restype=container&comp=list` returns **HTTP 200** and lists both blobs |
| Storage account | `allowSharedKeyAccess: true`, public access enabled, no network ACLs, TLS1_2 — identical to the working app |
| VNet | No integration on either app |
| RBAC | App identity holds Storage Blob Data Owner + Queue + Table Contributor |
| SCM basic auth policy | `allow: true` |
| `AzureWebJobsStorage` identity vs connection string | The only remaining difference. **Tested and reverted — not the cause.** Same 503. |
| App restart | Tried. No change. |
`kudu-state.json` in the deployment container still shows the 2026-08-19 deployment as both `ActiveDeploymentId` and `LatestDeploymentId`, `Complete: true`. Nothing since has written anything — the platform never records a deployment attempt at all.
### Question
Why can Kudu/SCM not start for a deployment on this app, when an identically configured Flex Consumption app in the same subscription deploys normally? SCM root returns 503 on the failing app.
### Possibly relevant history
On 2026-08-19 an ARM/Bicep deployment set `siteConfig.appSettings` as a REPLACE, removing 19 of 30 app settings including `DEPLOYMENT_STORAGE_CONNECTION_STRING`, and in the same write flipped `deployment.storage.authentication.type` to `SystemAssignedIdentity`. Both have since been repaired and now match the working app. The last successful deployment was immediately before that infra run.
### Deployment container state — inspected and cleared (29 Aug)
Two further things, since "check your deployment container" is the obvious first question:
**1. `kudu-state.json` inspected and diffed against the working app's.** Identical schema, identical 12-step list, identical field set. The failing app's last successful deployment (19 Aug) shows all 12 Kudu steps complete. **Neither file contains any URL, storage account reference, or SAS fragment** — nothing points at a pre-recreation world. The only differences are per-deployment values (correlation id, deployer, GUID paths) and history depth (1 recorded deployment vs 3).
**2. Deleting the two blobs takes the running app DOWN.** Worth recording as a platform behaviour note: with `released-package.zip` and `kudu-state.json` removed from the deployment container, `/api/health` went from 200 to **404** immediately — Flex Consumption mounts the package from blob storage at runtime, so the container is not merely a deployment staging area. Both blobs were restored byte-identical (sha256 verified) and the app returned to 200 within 8 seconds, 333 functions indexed.
This means "retry the deploy against an empty container" cannot be tested without taking production down for the duration, so we have **not** run that experiment cleanly — the restore landed 23 seconds before the Kudu step on the one attempt, so that run exercised a full container like all the others.
### Current state
The app is healthy and serving (200, 333 functions indexed). It is running a package from 2026-08-19 and has been unable to accept any deployment since. Every fix written in the last ten days is undeliverable.
### Environment
- SKU: FlexConsumption, `functionapp,linux`, Python 3.10
- `Azure/functions-action@v1`, `remote-build: true`, `package: '.'`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the failure reported in azure-app-kudu-service.js:274:41 and compare the action's Kudu deployment path with the direct az functionapp deployment source config-zip command. Check the SCM root response and the documented Flex app configuration differences; done means identifying an actionable change in this action or confirming the 503 is outside its control.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, github-actions, python, typescript
- Domain
- cloud, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100