How to fix Azure App Service deployment failures due to SCM site issues

Understanding Azure App Service SCM Site Deployment Failures

Azure App Service provides several deployment methods — local Git, FTP, ZIP deploy, and continuous integration — many of which depend on the SCM (Source Control Manager) site, also known as the Kudu endpoint. When the SCM site encounters issues, deployments fail with cryptic errors that can halt your CI/CD pipeline or manual deployment workflow entirely.

This guide walks through every common SCM-related deployment failure, explains the root cause, and provides tested fixes with exact CLI commands and portal navigation steps.

Diagnostic Context

When encountering Azure App Service deployment failures due to SCM site, the first step is understanding what changed. In most production environments, errors do not appear spontaneously. They are triggered by a change in configuration, code, traffic patterns, or the platform itself. Review your deployment history, recent configuration changes, and Azure Service Health notifications to identify potential triggers.

Azure maintains detailed activity logs for every resource operation. These logs capture who made a change, what was changed, when it happened, and from which IP address. Cross-reference the timeline of your error reports with the activity log entries to establish a causal relationship. Often, the fix is simply reverting the most recent change that correlates with the error onset.

If no recent changes are apparent, consider external factors. Azure platform updates, regional capacity changes, and dependent service modifications can all affect your resources. Check the Azure Status page and your subscription’s Service Health blade for any ongoing incidents or planned maintenance that coincides with your issue timeline.

Common Pitfalls to Avoid

When fixing Azure service errors under pressure, engineers sometimes make the situation worse by applying changes too broadly or too quickly. Here are critical pitfalls to avoid during your remediation process.

First, avoid making multiple changes simultaneously. If you change the firewall rules, the connection string, and the service tier all at once, you cannot determine which change actually resolved the issue. Apply one change at a time, verify the result, and document what worked. This disciplined approach builds reliable operational knowledge for your team.

Second, do not disable security controls to bypass errors. Opening all firewall rules, granting overly broad RBAC permissions, or disabling SSL enforcement might eliminate the error message, but it creates security vulnerabilities that are far more dangerous than the original issue. Always find the targeted fix that resolves the error while maintaining your security posture.

Third, test your fix in a non-production environment first when possible. Azure resource configurations can be exported as ARM or Bicep templates and deployed to a test resource group for validation. This extra step takes minutes but can prevent a failed fix from escalating the production incident.

Fourth, document the error message exactly as it appears, including correlation IDs, timestamps, and request IDs. If you need to open a support case with Microsoft, this information dramatically speeds up the investigation. Azure support engineers can use correlation IDs to trace the exact request through Microsoft’s internal logging systems.

How the SCM Site Works in App Service

Every Azure App Service has a companion SCM site accessible at https://<app-name>.scm.azurewebsites.net. This site hosts the Kudu engine, which handles:

  • Local Git deployment endpoints
  • FTP/FTPS file transfer
  • ZIP and WAR deploy APIs
  • Log streaming and diagnostic console
  • Process explorer and environment variable inspection

When the SCM site is misconfigured, inaccessible, or has authentication issues, any deployment method that routes through Kudu will fail. Understanding this architecture is the first step to diagnosing deployment problems.

Basic Authentication Disabled — The Most Common Cause

Starting in late 2023, Azure began disabling basic authentication on new App Service instances by default. This change affects both the SCM site and FTP endpoints. If your app was created recently, this is likely the first thing to check.

Symptoms

  • Local Git push returns fatal: Authentication failed
  • FTP connections are rejected immediately
  • Kudu dashboard returns HTTP 401 Unauthorized
  • ZIP deploy API calls return 401

Diagnosing the Issue

Check whether basic authentication is enabled for the SCM site:

# Check SCM basic auth status
az resource show \
  --resource-group myResourceGroup \
  --name scm \
  --namespace Microsoft.Web \
  --resource-type basicPublishingCredentialsPolicies \
  --parent sites/myAppName \
  --query properties.allow

If the output is false, basic authentication is disabled and you need to either enable it or switch to Microsoft Entra ID-based deployment.

Fix Option 1: Enable Basic Authentication

# Enable basic auth for SCM
az resource update \
  --resource-group myResourceGroup \
  --name scm \
  --namespace Microsoft.Web \
  --resource-type basicPublishingCredentialsPolicies \
  --parent sites/myAppName \
  --set properties.allow=true

# Enable basic auth for FTP
az resource update \
  --resource-group myResourceGroup \
  --name ftp \
  --namespace Microsoft.Web \
  --resource-type basicPublishingCredentialsPolicies \
  --parent sites/myAppName \
  --set properties.allow=true

Fix Option 2: Use Entra ID Authentication (Recommended)

Microsoft recommends using Entra ID-based deployment with tools that support it. Visual Studio 2022 (version 17.12+) and Azure CLI (version 2.48.1+) support Entra ID authentication for deployments, eliminating the need for basic auth entirely.

# Deploy using Azure CLI (uses Entra ID automatically)
az webapp deploy --resource-group myResourceGroup \
  --name myAppName \
  --src-path ./myapp.zip \
  --type zip

Audit Basic Auth Usage with Azure Policy

To enforce basic auth is disabled across all App Service instances in your organization:

# Monitor basic auth attempts via diagnostic logs
az monitor diagnostic-settings create \
  --resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app} \
  --name scm-audit \
  --logs '[{"category":"AppServiceAuditLogs","enabled":true}]' \
  --workspace {log-analytics-workspace-id}

App Is Stopped — Deployment Unavailable

Azure App Service does not accept Git deployments when the app is in a stopped state. This catches many developers off guard, especially when they stop an app to save costs during development.

Symptoms

  • Error: Unable to access 'https://<app>.scm.azurewebsites.net/': Failed to connect
  • Connection timeout when pushing to the Git remote
  • Kudu dashboard is unreachable

Fix

# Start the app
az webapp start --name myAppName --resource-group myResourceGroup

# Verify the app is running
az webapp show --name myAppName --resource-group myResourceGroup \
  --query "state" -o tsv

After starting the app, wait 30–60 seconds for the SCM site to become fully available before retrying the deployment.

Incorrect Git Remote URL

If the Azure Git remote URL is wrong — perhaps due to renaming the app or copying configuration from another project — Git push will fail with hostname resolution errors.

Symptoms

  • Error: Couldn't resolve host 'hostname'
  • Error: Repository not found

Fix

# Check current remote URL
git remote -v

# Remove incorrect remote
git remote remove azure

# Get the correct deployment URL
az webapp deployment source config-local-git \
  --name myAppName \
  --resource-group myResourceGroup \
  --query url -o tsv

# Add correct remote
git remote add azure https://myAppName.scm.azurewebsites.net/myAppName.git

Deployment Branch Mismatch

Azure App Service expects deployments on a specific branch (default: master). If your local repository uses a different default branch like main, the deployment will silently fail or produce confusing errors.

Symptoms

  • Error: No refs in common and none specified; doing nothing
  • Push succeeds but website doesn’t update
  • Error: Changes committed to remote repository but deployment to website failed

Fix Option 1: Push to the Correct Branch

# Push local main to remote master
git push azure main:master

Fix Option 2: Change the Deployment Branch

# Set deployment branch to match your local branch
az webapp config appsettings set \
  --name myAppName \
  --resource-group myResourceGroup \
  --settings DEPLOYMENT_BRANCH='main'

# Now push normally
git push azure main

Large Repository Push Failures

Pushing large repositories over HTTPS can fail due to HTTP buffer size limits. This is especially common with repositories containing binary assets, large datasets, or extensive Git history.

Symptoms

  • Error: RPC failed; result=22, HTTP code = 5xx
  • Push hangs and eventually times out
  • Error: error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL

Fix

# Increase Git HTTP buffer size to 500 MB
git config --global http.postBuffer 524288000

# For very large repos, consider shallow clone deployment
git clone --depth 1 <repo-url>

# Or use ZIP deploy instead of Git
az webapp deploy --resource-group myResourceGroup \
  --name myAppName \
  --src-path ./app.zip \
  --type zip

Root Cause Analysis Framework

After applying the immediate fix, invest time in a structured root cause analysis. The Five Whys technique is a simple but effective method: start with the error symptom and ask “why” five times to drill down from the surface-level cause to the fundamental issue.

For example, considering Azure App Service deployment failures due to SCM site: Why did the service fail? Because the connection timed out. Why did the connection timeout? Because the DNS lookup returned a stale record. Why was the DNS record stale? Because the TTL was set to 24 hours during a migration and never reduced. Why was it not reduced? Because there was no checklist for post-migration cleanup. Why was there no checklist? Because the migration process was ad hoc rather than documented.

This analysis reveals that the root cause is not a technical configuration issue but a process gap that allowed undocumented changes. The preventive action is creating a migration checklist and review process, not just fixing the DNS TTL. Without this depth of analysis, the team will continue to encounter similar issues from different undocumented changes.

Categorize your root causes into buckets: configuration errors, capacity limits, code defects, external dependencies, and process gaps. Track the distribution over time. If most of your incidents fall into the configuration error bucket, invest in infrastructure-as-code validation and policy enforcement. If they fall into capacity limits, improve your monitoring and forecasting. This data-driven approach focuses your improvement efforts where they will have the most impact.

Node.js Native Module Build Failures

When deploying Node.js applications, the SCM site runs npm install during deployment. Native modules that require compilation (using node-gyp) can fail on the App Service build environment.

Symptoms

  • Error: npm ERR! cmd "/c" "node-gyp rebuild" failed
  • Error: gyp ERR! build error
  • Deployment fails during the build step

Fix

# Option 1: Use a pre-built binary
npm install --platform=win32 --arch=x64

# Option 2: Build locally and deploy with node_modules
# Add to .deployment file:
[config]
SCM_DO_BUILD_DURING_DEPLOYMENT=false

# Option 3: Use Linux App Service (better native module support)
az webapp create --resource-group myResourceGroup \
  --plan myLinuxPlan \
  --name myAppName \
  --runtime "NODE:20-lts"

Custom Deployment Script Failures

If you use a .deployment file or custom deployment scripts, errors in your script configuration can cause the entire deployment pipeline to fail.

Diagnosing Custom Script Issues

# View deployment logs
az webapp log deployment show --name myAppName \
  --resource-group myResourceGroup

# Stream deployment logs in real time
az webapp log tail --name myAppName \
  --resource-group myResourceGroup

# Access Kudu console for manual debugging
# Navigate to: https://myAppName.scm.azurewebsites.net/DebugConsole

Common .deployment File Issues

# Correct .deployment file format
[config]
command = deploy.cmd

# Common mistakes:
# - Missing [config] section header
# - Wrong script path (relative to repo root)
# - Script lacks execute permissions (Linux)

SCM Site Network and Firewall Issues

Apps using private endpoints, VNet integration, or IP restrictions can block access to the SCM site, preventing deployments from external networks.

Fix: Configure SCM Access Restrictions

Navigate to Portal > App Service > Networking > Access restrictions. The SCM site has its own access restriction rules, separate from the main site.

# Add IP rule for SCM site
az webapp config access-restriction add \
  --resource-group myResourceGroup \
  --name myAppName \
  --rule-name "AllowDevOps" \
  --action Allow \
  --ip-address 203.0.113.0/24 \
  --priority 100 \
  --scm-site true

# Check current SCM access restrictions
az webapp config access-restriction show \
  --resource-group myResourceGroup \
  --name myAppName \
  --query scmIpSecurityRestrictions

Deployment Slot Swap Failures

When using deployment slots, the SCM site plays a role in slot swaps. If the staging slot’s SCM site has issues, the swap operation can fail or hang.

Symptoms

  • Swap operation times out
  • Swap fails with “Internal Server Error”
  • Staging slot shows unhealthy status post-swap

Fix

# Check deployment slot status
az webapp deployment slot list \
  --name myAppName \
  --resource-group myResourceGroup \
  --query "[].{name:name, state:state}"

# Reset the staging slot
az webapp restart --name myAppName \
  --resource-group myResourceGroup \
  --slot staging

# Verify the swap with preview
az webapp deployment slot swap \
  --name myAppName \
  --resource-group myResourceGroup \
  --slot staging \
  --target-slot production \
  --action preview

Diagnostic Checklist

Use this systematic checklist when troubleshooting any SCM site deployment failure:

  1. Is the app running? — Check app state is “Running”
  2. Is basic auth enabled? — Verify SCM basic auth policy
  3. Is the SCM site reachable? — Try accessing https://app.scm.azurewebsites.net
  4. Are credentials correct? — Reset deployment credentials if uncertain
  5. Is the Git remote URL correct? — Run git remote -v
  6. Are you pushing to the right branch? — Check DEPLOYMENT_BRANCH setting
  7. Are access restrictions blocking you? — Check SCM IP security restrictions
  8. Are deployment logs showing errors? — Check Kudu deployment logs
# Quick diagnostic script
APP_NAME="myAppName"
RG="myResourceGroup"

echo "=== App State ==="
az webapp show -n $APP_NAME -g $RG --query state -o tsv

echo "=== SCM Basic Auth ==="
az resource show -g $RG --name scm \
  --namespace Microsoft.Web \
  --resource-type basicPublishingCredentialsPolicies \
  --parent sites/$APP_NAME \
  --query properties.allow -o tsv

echo "=== Deployment Branch ==="
az webapp config appsettings list -n $APP_NAME -g $RG \
  --query "[?name=='DEPLOYMENT_BRANCH'].value" -o tsv

echo "=== Recent Deployments ==="
az webapp deployment list-publishing-credentials \
  -n $APP_NAME -g $RG \
  --query scmUri -o tsv

Prevention Best Practices

To avoid SCM site deployment failures proactively:

  • Use CI/CD pipelines — GitHub Actions and Azure DevOps handle authentication and deployment more reliably than manual Git push
  • Prefer ZIP deploy or Run From Package — These methods are more resilient than Git-based deployments for production workloads
  • Monitor deployment health — Enable Application Insights and set alerts on deployment failures
  • Use deployment slots — Deploy to staging first, validate, then swap to production
  • Keep the SCM site updated — Ensure platform version is current by selecting “Latest” in Configuration > General settings
  • Document deployment credentials — Store credentials in a key vault and rotate them regularly
  • Test SCM connectivity — Include a health check of the SCM site in your deployment pipeline

Tip: For production workloads, consider switching from SCM-based deployment to the az webapp deploy command, which uses the Kudu /api/publish endpoint and supports Entra ID authentication natively. This eliminates the most common class of SCM authentication failures.

Post-Resolution Validation and Hardening

After applying the fix, perform a structured validation to confirm the issue is fully resolved. Do not rely solely on the absence of error messages. Actively verify that the service is functioning correctly by running health checks, executing test transactions, and monitoring key metrics for at least 30 minutes after the change.

Validate from multiple perspectives. Check the Azure resource health status, run your application’s integration tests, verify that dependent services are receiving data correctly, and confirm that end users can complete their workflows. A fix that resolves the immediate error but breaks a downstream integration is not a complete resolution.

Implement defensive monitoring to detect if the issue recurs. Create an Azure Monitor alert rule that triggers on the specific error condition you just fixed. Set the alert to fire within minutes of recurrence so you can respond before the issue impacts users. Include the remediation steps in the alert’s action group notification so that any on-call engineer can apply the fix quickly.

Finally, conduct a brief post-incident review. Document the root cause, the fix applied, the time to detect, diagnose, and resolve the issue, and any preventive measures that should be implemented. Share this documentation with the broader engineering team through a blameless post-mortem process. This transparency transforms individual incidents into organizational learning that raises the entire team’s operational capability.

Consider adding the error scenario to your integration test suite. Automated tests that verify the service behaves correctly under the conditions that triggered the original error provide a safety net against regression. If a future change inadvertently reintroduces the problem, the test will catch it before it reaches production.

Summary

SCM site deployment failures in Azure App Service stem from a handful of root causes: disabled basic authentication, stopped apps, incorrect Git remotes, branch mismatches, network restrictions, and build environment issues. By systematically checking each of these areas using the diagnostic commands and checklist provided, you can identify and resolve any SCM-related deployment issue quickly. Moving toward Entra ID-based authentication and CI/CD pipelines will prevent the majority of these failures from occurring in the first place.

For more details, refer to the official documentation: App Service overview, Enable diagnostic logging for apps in Azure App Service, Secure your Azure App Service deployment.

Leave a Reply