Azure / Azure/functions-action

Flex Consumption: every deploy fails with Kudu 'Site Unavailable (CODE: 503)'; identical Flex app in same subscription deploys fine

Open
#390 5 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.