Azure Container Apps ImagePullBackOff Error

Issue encountered when deploying .NET applications to Azure Container Apps using GitHub Actions where the deployment succeeds but Kubernetes fails to pull the container image.

Error: ImagePullBackOff

Symptoms

GitHub Actions workflow completes successfully using azure/container-apps-deploy-action@v1, but the Container App shows:

1
1/1 Pending:ImagePullBackOff

Container logs show:

1
2
3
Connecting to stream...
2026-01-08T02:24:08.98852 Connecting to the container 'stew-app-uat'...
2026-01-08T02:24:09.00980 Kubernetes error happened. Closing the connection.

Root Cause

The Container App was created without registry authentication credentials configured. When checking the Container App configuration:

1
az containerapp show --name my-app --resource-group my-rg --query "{registries:properties.configuration.registries, secrets:properties.configuration.secrets}" -o json

Returns:

1
2
3
4
{
"registries": null,
"secrets": null
}

This means Kubernetes has no credentials to authenticate with the private Azure Container Registry (ACR) when pulling images, resulting in ImagePullBackOff.

What We Tried (That Didn’’t Work)

  1. Added AcrPull role to Service Principal: Assigned the AcrPull role to the deployment service principal on the ACR

    1
    az role assignment create --assignee SP_ID --role AcrPull --scope /subscriptions/.../Microsoft.ContainerRegistry/registries/myacr
    • Result: Still failed. The role is needed but not sufficient.
  2. Hardcoded image name and tag: Removed all variables to eliminate any interpolation issues

    1
    imageToDeploy: myregistry.azurecr.io/myapp:d989965
    • Result: Still failed. Image path was correct.
  3. Added acrUsername and acrPassword to GitHub Action: Provided explicit credentials to the deploy action

    1
    2
    3
    4
    with:
    acrName: myregistry
    acrUsername: ${{ secrets.ACR_USER }}
    acrPassword: ${{ secrets.ACR_PASSWORD }}
    • Result: Still failed. The action didn’’t properly configure these on the Container App.

The Solution

The Container App itself needs registry credentials configured. This must be done manually using Azure CLI:

1
2
3
4
5
6
az containerapp registry set `
--name my-container-app `
--resource-group my-rg `
--server myregistry.azurecr.io `
--username myregistry `
--password ''YOUR_ACR_PASSWORD''

Important: Use single quotes around the password to preserve special characters like /, +, !.

After running this command, verify the configuration:

1
az containerapp show --name my-app --resource-group my-rg --query "properties.configuration.registries" -o json

Should return:

1
2
3
4
5
6
7
8
[
{
"identity": "",
"passwordSecretRef": "myregistryazurecrio-myregistry",
"server": "myregistry.azurecr.io",
"username": "myregistry"
}
]

Now the Container App can successfully pull images from the private ACR.

Why This Happens

The azure/container-apps-deploy-action@v1 GitHub Action has a bug or limitation where it doesn’’t properly configure registry credentials on the Container App, even when acrUsername and acrPassword parameters are provided.

The action successfully:

  • Authenticates with Azure
  • Updates the Container App definition
  • Sets the new image path

But it fails to:

  • Create the registry credential secret
  • Configure the registry authentication in the Container App

Comparison with Working Configuration

A working Container App deployed through other means shows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"registries": [
{
"identity": "",
"passwordSecretRef": "myregistryazurecrio-myregistry",
"server": "myregistry.azurecr.io",
"username": "myregistry"
}
],
"secrets": [
{
"name": "myregistryazurecrio-myregistry"
}
]
}

Prevention

  1. Always verify registry configuration after first deployment:

    1
    az containerapp show --name my-app --resource-group my-rg --query "properties.configuration.registries"
  2. Keep acrUsername and acrPassword in your workflow: While the initial deployment might not configure them, subsequent deployments may maintain the configuration once it’’s set manually.

  3. Consider using Managed Identity: For production, configure the Container App to use managed identity for ACR authentication instead of username/password:

    1
    2
    3
    4
    5
    6
    {
    "registries": [{
    "server": "myregistry.azurecr.io",
    "identity": "system"
    }]
    }

Key Takeaway

GitHub Action success Deployment success. The action updates the Container App definition, but Kubernetes pulls the image after the action completes. Always check:

  1. GitHub Action completed
  2. Container App revision status
  3. Container logs for pull errors

The ImagePullBackOff error specifically means authentication failed between Kubernetes and your private registry.