Symptoms
- Queue or Service Bus messages pile up; timer functions have no executions in Application Insights.
- The portal shows the function app as Running, but
Monitorhas no invocations. - It started after a storage account change, key rotation, network lockdown or deployment.
1. Ask the host what it thinks
APP=func-orders-prod; RG=rg-orders
KEY=$(az functionapp keys list -g $RG -n $APP --query masterKey -o tsv)
curl -s "https://$APP.azurewebsites.net/admin/host/status?code=$KEY"
state should be Running. Error with a list of errors is the fastest diagnosis you will get. If the call itself fails, the host cannot start at all.
2. Look at host errors in Application Insights
traces
| where timestamp > ago(1h)
| where severityLevel >= 3
| summarize count() by message
| top 20 by count_
exceptions
| where timestamp > ago(1h)
| summarize count() by type, outerMessage
| top 20 by count_
| Error text | Cause | Fix |
|---|---|---|
Storage account connection string ... does not exist or 403 on blobs | AzureWebJobsStorage wrong, key rotated or firewall | Step 3 |
The listener for function ... was unable to start | Trigger connection setting wrong or service unreachable | Check the trigger connection app setting |
Function host is not running after deploy | Missing extension, bad host.json, wrong FUNCTIONS_WORKER_RUNTIME | Fix config, redeploy |
Singleton lock renewal failures | Storage latency or access issues | Step 3 |
3. Fix the storage connection
The host uses AzureWebJobsStorage for leases, timers and keys. If that breaks, timer and queue triggers stop.
az functionapp config appsettings list -g $RG -n $APP \
--query "[?starts_with(name,'AzureWebJobsStorage')]" -o table
- Key rotated: update the connection string, or better, move to identity-based connections (
AzureWebJobsStorage__accountName) with the right roles on the storage account (Storage Blob Data Owner, plus Queue and Table roles where needed). - Firewall turned on: the function app needs VNet integration and the storage account must allow that subnet or use private endpoints for blob, queue, table (and file for Consumption/Premium content share).
- Storage account deleted or recreated: point the setting at the new account; expect timer schedules to reset.
az functionapp config appsettings set -g $RG -n $APP \
--settings "AzureWebJobsStorage=<connection-string-or-use-identity>"
az functionapp restart -g $RG -n $APP
Warning
Do not share one
AzureWebJobsStorageaccount between many busy function apps. Lease and host ID collisions cause triggers that randomly stop firing.
4. Check that the functions are not disabled
az functionapp config appsettings list -g $RG -n $APP \
--query "[?starts_with(name,'AzureWebJobs.') && ends_with(name,'.Disabled')]" -o table
A leftover AzureWebJobs.<FunctionName>.Disabled=true from a test silently disables one function.
5. Scale and plan checks
- Consumption with VNet-restricted triggers: scale controller cannot see the queue. Use Premium or Flex Consumption and turn on runtime scale monitoring:
az resource update -g $RG -n $APP/config/web --resource-type Microsoft.Web/sites \
--set properties.functionsRuntimeScaleMonitoringEnabled=true
- Dedicated plan:
Always Onmust be enabled or timer and queue triggers stop after idle.
az functionapp config set -g $RG -n $APP --always-on true
6. Drain the backlog safely
After the host is healthy, watch the queue length come down. If downstream systems cannot take the burst, cap concurrency in host.json (batchSize, maxConcurrentCalls depending on the extension) and redeploy rather than letting every instance hammer the database.
Prevent it next time
- Alert on "no executions in N minutes" for critical timer functions and on queue length age.
- Use identity-based connections so key rotation cannot break the host.
- Give each production function app its own storage account.
- Include a host status check in deployment smoke tests.