Azure / Azure/azure-cli-extensions

az containerapp up recreates an existing Container App (wiping all config) when the pre-deploy existence check fails with a transient/network error instead of a 404

Open
#10,103 1 comment 1 reaction 0 assignees View on GitHub
act-observability-squad Auto-Assign bug ContainerApp customer-reported Service Attention
Dominant language
Python
Stars
454
Forks
1.7k
Avg merge
2d 19h
Merged PRs (30d)
64

Description

### Describe the bug

When `az containerapp up` deploys a pre-built image to an app that already exists, it first runs `az containerapp show` to decide whether to update or create. If that `show` call fails with a transient error (in our case a network connectivity failure to management.azure.com, not a 404 / ResourceNotFound), `up` proceeds as if the app does not exist and runs `az containerapp create` with only the image and default ingress settings.

Because `create` against an existing app is a full-spec replace, this silently wipes the entire configuration of a running production app: all environment variables, all secrets, the managed identity, and custom domain bindings are dropped, and the ingress `--target-port` is reset to the default (80). The app immediately stops serving, and the command exits 0 (success). This turned a routine image deploy into a ~40 minute production outage.

The day before, the same command against the same app ran `az containerapp update -i` (the existence check succeeded) and behaved correctly. The only difference was the transient failure of the `show` call.

### Related command

`az containerapp up`, as invoked by the azure/container-apps-deploy-action@v2 GitHub Action (action SHA 8dff69dac3367c32ceb2690d8f13adbeab462703) in pre-built image mode (imageToDeploy, no appSourcePath/dockerfilePath).

### Errors

The pre-deploy existence check `az containerapp show` failed with a transient network error (not a 404), and `az containerapp up` then fell through to `az containerapp create`, which recreated and wiped the app. Sanitized runner logs:

```
[command] az containerapp show -n -g -o none
ERROR: The command failed with an unexpected error. Here is the traceback:
ERROR: HTTPSConnectionPool(host='management.azure.com', port=443): Max retries exceeded with url:
/subscriptions//resourceGroups//providers/Microsoft.App/containerApps/?api-version=2025-10-02-preview
(Caused by NewConnectionError(... [Errno 101] Network is unreachable))
...
Default ingress value: external
Creating Container App "" from command line arguments...
[command] az containerapp create -n -g --environment --output none --registry-server .azurecr.io --registry-username *** --registry-password *** --ingress external --target-port 80 -i .azurecr.io/:
```

After this command the app had an empty env var list, only the auto-added registry secret, no managed identity, no custom domain, and target-port 80 (the app listens on 3000). The command reported success.

### Issue script & Debug output

This ran inside the azure/container-apps-deploy-action@v2 in CI, so `--debug` output is not available. The observed command sequence from the runner logs (sanitized) was:

```
az containerapp show -n -g -o none # FAILED: Network is unreachable to management.azure.com
az containerapp show -n -g --query properties.environmentId
az containerapp env show -g -n
az containerapp show -n -g -o none # existence check
# up then decided the app did not exist and ran:
az containerapp create -n -g --environment --ingress external --target-port 80 -i .azurecr.io/:
```

The `containerapp` extension was auto-installed via `az extension add --name containerapp --upgrade` ("No stable version of 'containerapp' to install. Preview versions allowed."), and the failing call used ARM api-version 2025-10-02-preview. A separate CI job on the same runner in the same minutes also failed on runner infrastructure (`Error response from daemon: received unexpected HTTP status: 500`), which points to a transient GitHub-hosted-runner network incident as the trigger.

### Expected behavior

`az containerapp up` should only take the create path when the app is confirmed absent (an explicit ResourceNotFound / 404 from the existence check). On a transient or ambiguous error (network failure, 5xx, timeout, throttling), it should retry or fail the command, never fall through to recreating an existing resource. When updating an existing app it should also not reset the ingress target-port (or other configuration) to a default that was not supplied. In short: a transient control-plane hiccup should never silently recreate and wipe a live app.

### Environment Summary

Ran on a GitHub-hosted `ubuntu-latest` runner using the azure-cli bundled on that runner image (exact `az --version` from the runner was not captured). The `containerapp` extension was auto-installed as a preview build via `az extension add --name containerapp --upgrade` ("No stable version of 'containerapp' to install. Preview versions allowed."). Observed ARM API version in the failing call: 2025-10-02-preview. Invoked through azure/container-apps-deploy-action@v2 (SHA 8dff69dac3367c32ceb2690d8f13adbeab462703).

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by locating the Python implementation of `az containerapp up` and its `az containerapp show` existence check, then inspect how network errors differ from an explicit 404. Reproduce the create/update decision if possible; done means transient, 5xx, timeout, or throttling errors retry or fail, while only confirmed absence takes the create path without resetting unspecified configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, python
Domain
cli, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.