Flex Consumption (.NET 8 isolated) - storage queue trigger does not process messages until always-ready pin

Mahmoud Mahajna 20 Reputation points
2026-06-30T16:07:34.67+00:00

Environment


  • Azure Functions - Flex Consumption plan (Linux)
  • .NET 8 isolated worker
  • Single function app with multiple triggers (HTTP, timer, Cosmos change feed, Durable, and one storage queue trigger)
  • Storage queue used for background processing (timer enqueues, queue trigger dequeues and processes)
  • AzureWebJobsStorage and a separate app setting for the queue connection (same storage account)
  • Scale config: always-ready on HTTP (http = 1)
  • scaleAndConcurrency.triggers is {} (we tried setting it to null - did not help; reverted to {}; queue still works when pinned with triggers: {})

Deployment


  • CI/CD via Azure DevOps
  • AzureFunctionApp@2 task with isFlexConsumption: true (One Deploy)
  • dotnet publish → zip → deploy
  • Not using func publish --build local

Scenario


A timer function enqueues messages to a storage queue on a schedule.

A queue-triggered function should pick up those messages and run the business logic.

Expected


When messages are in the queue, Flex should scale the queue function (scale-from-zero) and process them automatically.

Actual


  • Messages sit in the queue with dequeueCount: 0 for a long time — nothing dequeues them.
  • Log stream on a running instance shows blob activity (host locks, health checks) but no traffic to *.queue.core.windows.net.
  • HTTP always-ready keeps an instance warm, but the queue is not polled on that instance.
  • Pinning the queue function with always-ready (function:<QueueFunctionName>=1) processes the queue immediately — end-to-end success.
  • Temporarily pin → drain → unpin sometimes restores scale-from-zero for a while; the issue tends to return after deployment.
  • Other triggers on the same app (HTTP, timer, Cosmos) work normally from zero.

What we've ruled out


We do not think this is a misconfiguration:

  • Queue binding, connection string, and code are validated - pinning the queue function works without any config change.
  • triggers: {} is present when it fails and also when pin makes it work (null did not fix it).
  • Same deployment path and app structure; regression appears tied to deploy cycles.

Question


Is this a known Flex Consumption issue with storage queue trigger registration / Scale Controller monitoring after One Deploy?

Why would RefreshTrigger / host startup look healthy while the queue is never polled until the queue function is pinned?

Any guidance beyond permanent always-ready on the queue function would be appreciated.

Azure Functions
Azure Functions

An Azure service that provides an event-driven serverless compute platform.


Answer accepted by question author
Pravallika KV 18,850 Reputation points Microsoft External Staff Moderator
2026-06-30T16:47:04.62+00:00

Hi @Mahmoud Mahajna ,

Thanks for reaching out to Microsoft Q&A.

On Flex Consumption, trigger activation for scale-from-zero depends on per-function scaling behavior and Always Ready capacity. The queue trigger itself uses a polling/backoff loop for messages, but that polling only happens when the runtime/scale allocation for that specific queue-trigger function is actually active.

Even if the app is healthy, the queue-trigger function may not be allocated an active instance during scale-from-zero under your deployment conditions, and therefore the queue polling loop never starts.

Update:

The issue appears to be related to intermittent Storage Queue trigger initialization/scaling behavior in Azure Functions Flex Consumption (Linux) with .NET 8 isolated worker, particularly after deployments or cold starts.

Our engineering teams have reviewed the scaling and trigger monitoring components and confirmed that the platform is monitoring the queue trigger and scaling behavior correctly when messages are detected. We are continuing to investigate scenarios where trigger initialization may impact queue message detection.

If you encounter this issue again, we recommend collecting the following details to help with further investigation:

  • Function App name and region
  • Approximate time of occurrence
  • Deployment timeline (if applicable)
  • Queue trigger logs and Application Insights traces
  • Function runtime and extension versions

For now, the always-ready configuration remains the recommended mitigation. If the issue reoccurs after future deployments, please share the above details so we can continue troubleshooting.

Hope this helps!


If the resolution was helpful, kindly take a moment to click on User's imageand click on Yes for was this answer helpful. And, if you have any further query do let us know.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Jerald Felix 18,680 Reputation points Volunteer Moderator
    2026-06-30T16:47:57.8+00:00

    Hello Mahmoud Mahajna,

    Greetings! Thanks for raising this question in the Q&A forum.

    What you are describing matches a known gap in Flex Consumption between a successful deployment and the trigger metadata actually being synced to the external Scale Controller. The Scale Controller that wakes your app from zero for non HTTP triggers (queue, Service Bus, Event Hubs, Cosmos) does not read your code directly. It relies on a separate sync step that registers each trigger's binding metadata with the platform after deployment. When that sync does not happen cleanly, the host itself starts up fine, Cosmos and Durable and timer triggers keep working because some of those paths use different scaling signals, but the Scale Controller has no record of the queue trigger and never polls it. Pinning the function with always ready forces an instance to stay warm, and once warm the in-process WebJobs SDK listener takes over and polls the queue directly, which is exactly why pinning "fixes" it without any code change. This has been seen with other Flex Consumption deployment paths as well, not just yours, so it is not something specific to your binding or connection string configuration.

    1. Confirm this is a trigger sync issue rather than a code issue Since pinning already proves your code, connection string, and permissions are correct, you can treat this purely as a deployment and platform sync problem rather than re-checking the function itself. Force a remote build instead of relying only on isFlexConsumption in the pipeline task Flex Consumption strictly needs a server side (Kudu/SCM) build so the platform can correctly extract and sync trigger metadata as part of deployment. With dotnet publish then zip then AzureFunctionApp@2, confirm the task is actually performing a One Deploy remote build and not just uploading a prebuilt zip as a package reference. Explicitly set the app setting below so the SCM site performs the build and sync step server side:
    - task: AzureFunctionApp@2
      inputs:
        azureSubscription: '<your-service-connection>'
        appType: 'functionAppLinux'
        appName: '<your-function-app>'
        package: '$(Build.ArtifactStagingDirectory)/**/*.zip'
        isFlexConsumption: true
        deploymentMethod: 'zipDeploy'
    

    And on the function app itself, confirm SCM_DO_BUILD_DURING_DEPLOYMENT is not set to false, since that would skip the remote build path that performs trigger registration.

    Add an explicit SyncTriggers call right after the deploy step

    Even with a correct remote build, add a pipeline step that explicitly forces a trigger sync after deployment so the Scale Controller is guaranteed to have current metadata:

    az rest --method post \
      --url "https://management.azure.com/subscriptions/<subId>/resourceGroups/<rg>/providers/Microsoft.Web/sites/<appName>/syncfunctiontriggers?api-version=2023-12-01"
    

    Verify trigger registration after deploy using Kudu

    After a deployment, browse to https://<appName>.scm.azurewebsites.net/api/functions and confirm the queue triggered function is listed with its binding type and connection details populated. If it is missing or shows an empty bindings array right after a deploy that later fails to scale, that confirms the sync did not complete, and a manual call to step 3 should immediately restore scale from zero without needing to pin.

    Watch for the regression returning after each deployment

    Since you noted the issue tends to come back after a new deploy, build the SyncTriggers call into the pipeline permanently as in step 3 rather than only running it manually, until this is resolved at the platform level.

    Escalate to Azure Support with a deployment timestamp and resource ID

    This is a confirmed pattern affecting non HTTP triggers specifically in Flex Consumption after One Deploy, so if the explicit SyncTriggers workaround does not fully and permanently resolve it for you, open a support case referencing trigger sync failures between One Deploy and the Scale Controller, and include a deployment timestamp plus your function app resource ID so the team can correlate it against the Scale Controller logs on their side.

    For reference on scaling behavior and per-function scaling groups in Flex Consumption, see:

    https://learn.microsoft.com/en-us/azure/azure-functions/event-driven-scaling
    https://learn.microsoft.com/en-us/azure/azure-functions/flex-consumption-plan
    

    If this answer helps you kindly accept the answer which will help others who have similar questions.

    Best Regards,

    Jerald Felix.

    Was this answer helpful?


  2. Yehor Diriavka 5 Reputation points
    2026-06-30T16:46:52.3766667+00:00

    Hello @Mahmoud Mahajna

    Welcome to Microsoft Q&A, and thank you for providing detailed information about your environment and deployment process.

    According to the Microsoft documentation, Azure Functions Flex Consumption uses per-function scaling. HTTP triggers scale together as a group on the same instances. Blob Storage Event Grid triggers and Durable Functions also use their own shared groups. Other trigger types scale independently on their own instances. The platform identifies individually scaled functions by using the function:<FUNCTION_NAME> convention.

    Always-ready instances are assigned to a specific per-function scaling group or an individual function. The default number of always-ready instances is zero. When always-ready instances are configured for the HTTP group, those instances are kept running for the HTTP functions in that group.

    Therefore, the http = 1 configuration applies to the HTTP scaling group. To assign an always-ready instance to an independently scaled function, Microsoft documents the function:<FUNCTION_NAME> format.

    Microsoft also documents that the Azure Storage Queue trigger starts a function when a new item is received in a queue. The queueName property specifies the queue to poll, and the connection property points to the application setting used to connect to Azure Queue Storage.

    Your deployment method is supported. One Deploy is the only deployment technology available for Function Apps running on the Flex Consumption plan. Microsoft also states that the Azure DevOps task uses One Deploy when it detects that a Flex Consumption application is being deployed.

    I would recommend opening the Function App in the Azure portal and navigating to:

    Diagnose and solve problems → search for Flex Consumption Deployment

    Microsoft provides this diagnostic tool for Flex Consumption deployments. It displays deployment history, package status, and troubleshooting recommendations.

    Microsoft documents that the Functions infrastructure must be aware of trigger changes. Trigger synchronization occurs automatically for many deployment technologies. Microsoft also provides the following two methods for manually synchronizing triggers:

    Restart the Function App in the Azure portal. The Functions host performs a background trigger synchronization after the application starts.

    Send an HTTP POST request to the syncfunctiontriggers API by using the following documented Azure CLI command:

    az rest \
      --method post \
      --url "https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Web/sites/<APP_NAME>/syncfunctiontriggers?api-version=2016-08-01"
    

    I would recommend reviewing the Flex Consumption deployment diagnostics and then testing both documented trigger synchronization methods.

    If the issue continues after these steps, please contact Azure Support for further assistance.

    I hope this information is helpful.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.