Azure Functions Flex Consumption (.NET 10 isolated): Storage Queue trigger discovered by host but never scales from zero

2026-08-16T21:31:41.53+00:00

I have referred to https://learn.microsoft.com/en-ca/answers/questions/5934284/flex-consumption-net-8-isolated-storage-queue-trig which doesn't really say anything useful other than "it may work... if not open a support ticket", but I'm getting asked to create here first

I’m investigating what appears to be a trigger-metadata / scale-controller issue with an Azure Functions Flex Consumption application, and would appreciate guidance on how to diagnose or correct it without configuring an always-ready instance.

Environment

  • Azure Functions Flex Consumption, Linux
  • .NET 10 isolated worker
  • 512 MB instances, maximum 10 instances
  • Azure Storage Queue trigger
  • Identity-based Storage connection / managed identity
  • Storage account accessed using private networking
  • Function App uses VNet integration
  • Infrastructure deployed using Bicep via Azure DevOps
  • No always-ready instances configured

The ingress Function App contains three functions:

GraphMailWebhook                 HTTP trigger
MaintainGraphMailSubscription    Timer trigger
ProcessGraphMailNotification     Azure Storage Queue trigger

The intended flow is:

Microsoft Graph
      |
      v
GraphMailWebhook
      |
      v
graph-mail-notifications Storage Queue
      |
      v
ProcessGraphMailNotification

The HTTP Graph webhook works. For example:

POST api/graph/notifications
result=202
success=True

The Functions host also clearly discovers the queue-triggered function:

Found the following functions:
Host.Functions.GraphMailWebhook
Host.Functions.MaintainGraphMailSubscription
Host.Functions.ProcessGraphMailNotification

and the queue extension starts with:

QueuesOptions
{
  "BatchSize": 8,
  "NewBatchThreshold": 4,
  "MaxPollingInterval": "00:01:00",
  "MaxDequeueCount": 5,
  "VisibilityTimeout": "00:01:00",
  "MessageEncoding": "Base64"
}

However, after the HTTP invocation the only Flex function group I see instantiated is:

Function group target is http

I never see a corresponding:

function:ProcessGraphMailNotification

and ProcessGraphMailNotification does not execute.

There are no current startup errors or queue-trigger function exceptions in the logs.

Things already checked

RBAC has been deliberately scoped tightly rather than giving the Function App broad Storage Contributor rights. The ingress managed identity has the appropriate Storage Queue data-plane permissions on the exact queue, including Storage Queue Data Message Processor.

The producer/consumer message encoding has also been made explicitly Base64 at both ends. We previously had an encoding mismatch which caused messages to reach MaxDequeueCount; that behaviour has now disappeared.

We also checked the actual deployed Flex configuration using ARM:

{
  "alwaysReady": 
  "instanceMemoryMB": 
  "maximumInstanceCount": 
  "triggers": 
}

This is important because I found another Microsoft Q&A report where the same symptom was caused by:

"triggers"

instead of null. That is not the case here.

I also do not want to solve this by permanently configuring an always-ready instance. My understanding is that Flex Consumption supports event-driven scale-to-zero for non-HTTP functions, and always-ready should be an optional cold-start optimisation rather than a requirement for a Storage Queue trigger to function.

Trigger resync

I am now testing an explicit trigger metadata resync using:

az
  
  

The REST API documentation describes this operation as synchronising function trigger metadata to the management database.

Questions

  1. In Flex Consumption, should ProcessGraphMailNotification normally cause a function:ProcessGraphMailNotification scale group to be created from zero when a Storage Queue message arrives, with no always-ready configuration?
  2. Is an explicit syncfunctiontriggers call expected or recommended after deploying a Flex Function App using private networking/VNet integration?
  3. Is there a supported way to inspect the trigger metadata that the Flex scale controller currently has registered for the Function App? The runtime host clearly knows about the function, but I would like to establish whether the scale controller does.
  4. If syncfunctiontriggers fixes this, should that operation be incorporated explicitly into an Azure DevOps deployment pipeline, or should a normal Functions deployment already perform this automatically?
  5. Are there known issues around trigger synchronisation when a Flex Function App uses VNet integration/private endpoints which could leave HTTP functions operational while non-HTTP scale-from-zero triggers are not registered correctly?

I’m particularly interested in identifying the underlying configuration/deployment issue rather than using an always-ready instance to mask it, as maintaining continuously allocated compute would undermine the reason for using Flex Consumption for this relatively low-volume workload.

I can provide the Bicep for the Function ApI’m investigating what appears to be a trigger-metadata / scale-controller issue with an Azure Functions Flex Consumption application, and would appreciate guidance on how to diagnose or correct it without configuring an always-ready instance.

Environment

  • Azure Functions Flex Consumption, Linux
  • .NET 10 isolated worker
  • 512 MB instances, maximum 10 instances
  • Azure Storage Queue trigger
  • Identity-based Storage connection / managed identity
  • Storage account accessed using private networking
  • Function App uses VNet integration
  • Infrastructure deployed using Bicep via Azure DevOps
  • No always-ready instances configured

The ingress Function App contains three functions:

GraphMailWebhook                 HTTP trigger
MaintainGraphMailSubscription    Timer trigger
ProcessGraphMailNotification     Azure Storage Queue trigger

The intended flow is:

Microsoft Graph
      |
      v
GraphMailWebhook
      |
      v
graph-mail-notifications Storage Queue
      |
      v
ProcessGraphMailNotification

The HTTP Graph webhook works. For example:

POST api/graph/notifications
result=202
success=True

The Functions host also clearly discovers the queue-triggered function:

Found the following functions:
Host.Functions.GraphMailWebhook
Host.Functions.MaintainGraphMailSubscription
Host.Functions.ProcessGraphMailNotification

and the queue extension starts with:

QueuesOptions
{
  "BatchSize": 8,
  "NewBatchThreshold": 4,
  "MaxPollingInterval": "00:01:00",
  "MaxDequeueCount": 5,
  "VisibilityTimeout": "00:01:00",
  "MessageEncoding": "Base64"
}

However, after the HTTP invocation the only Flex function group I see instantiated is:

Function group target is http

I never see a corresponding:

function:ProcessGraphMailNotification

and ProcessGraphMailNotification does not execute.

There are no current startup errors or queue-trigger function exceptions in the logs.

Things already checked

RBAC has been deliberately scoped tightly rather than giving the Function App broad Storage Contributor rights. The ingress managed identity has the appropriate Storage Queue data-plane permissions on the exact queue, including Storage Queue Data Message Processor.

The producer/consumer message encoding has also been made explicitly Base64 at both ends. We previously had an encoding mismatch which caused messages to reach MaxDequeueCount; that behaviour has now disappeared.

We also checked the actual deployed Flex configuration using ARM:

{
  "alwaysReady": 
  "instanceMemoryMB": 
  "maximumInstanceCount": 
  "triggers": 
}

This is important because I found another Microsoft Q&A report where the same symptom was caused by:

"triggers"

instead of null. That is not the case here.

I also do not want to solve this by permanently configuring an always-ready instance. My understanding is that Flex Consumption supports event-driven scale-to-zero for non-HTTP functions, and always-ready should be an optional cold-start optimisation rather than a requirement for a Storage Queue trigger to function.

The call succeeds and causes the app/host to reload its function metadata, but the queue function still does not execute. Following the sync, telemetry again shows ProcessGraphMailNotification being discovered, but no queue-trigger invocation occurs.

During host recycling I can see:

ProcessGraphMailNotification Stopping the listener ...
ProcessGraphMailNotification Stopped the listener ...
DrainMode mode enabled

After the subsequent host startup the function is discovered again, but still doesn't consume the queue.

There is no current exception, binding failure or authorization error in the Function App logs.

Expected behaviour

My understanding of Flex Consumption per-function scaling is that a Storage Queue function should scale independently as:

function:ProcessGraphMailNotification

and should not require an always-ready instance merely to consume a queue.

Questions

    1. Is there any additional trigger-registration step required for a Storage Queue trigger on Flex Consumption when the queue is behind a private endpoint and the app uses managed identity?
  1. Is there a way to inspect the trigger metadata registered with the Flex scale controller, rather than just the metadata seen by the running Functions host?
  2. Is there specific scale-controller telemetry available to show why function:ProcessGraphMailNotification is not being instantiated?
  3. Is an always-ready instance expected/required for this combination, or should normal event-driven scale-from-zero work?
    1. Are there any known current issues involving Flex Consumption + Storage Queue triggers + private endpoints/managed identity? I'm specifically trying to avoid using an always-ready instance as a workaround because that defeats part of the serverless cost model for a low-volume workload.

I can provide the Bicep for the Function App

Azure Functions
Azure Functions

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


1 answer

Sort by: Most helpful
  1. Allan Solomon Mejia 6,240 Reputation points
    2026-08-16T21:50:04.05+00:00

    Hello @Mike Hudgell - Lead Volunteer

    Your expectation is correct: on Flex Consumption, a Storage Queue-triggered function should be able to scale independently from zero. Always-ready instances default to zero and are intended to reduce cold-start latency; they are not a requirement for queue processing. Microsoft also documents that non-HTTP triggers generally receive their own per-function scale group in Flex Consumption.

    Given your evidence, I would separate host discovery from scale-controller registration. The Functions host clearly discovers ProcessGraphMailNotification, but that alone does not prove that the Flex scale controller has usable trigger metadata for scaling that function from zero.

    A few points:

    1. syncfunctiontriggers should not normally be required after every standard Functions deployment. Trigger synchronization is part of normal deployment behavior. Microsoft documents manual trigger synchronization for specific deployment models, such as when the app references a package whose contents are changed without changing its URL.
    2. Since you've already run a trigger sync successfully and the host rediscovered the queue function, but the queue still isn't consumed, I would not add syncfunctiontriggers blindly to the Azure DevOps pipeline yet. That risks masking the real issue.
    3. Enable verbose scale-controller telemetry:
    az functionapp config appsettings set \
      --name <FUNCTION_APP_NAME> \
      --resource-group <RESOURCE_GROUP> \
      --settings SCALE_CONTROLLER_LOGGING_ENABLED=AppInsights:Verbose
    

    Microsoft documents this specifically for sending detailed scale-controller decisions to Application Insights.

    That telemetry is probably the most useful next step because it can show whether the scale controller is seeing the queue trigger and why it is, or is not requesting an instance.

    1. I would also concentrate on the private Storage path. Your running instance can access the queue through VNet integration, but scale-from-zero requires the platform's trigger-scaling machinery to correctly monitor the event source. Flex Consumption supports VNet integration, managed identities, and dynamic scaling to zero, so this combination should be supported in principle.

    At this point, because:

    • the host discovers the queue function,
    • RBAC and Base64 handling have already been checked,
    • trigger synchronization completes,
    • there are no binding/startup exceptions,
    • no function:ProcessGraphMailNotification scale group appears, and
    • the trigger still fails only when relying on scale-from-zero,

    I think this is strong enough to justify an Azure Functions backend investigation, especially around the trigger metadata/scale-controller path for the private Storage endpoint.

    I wouldn't recommend configuring an always-ready instance as the permanent fix. It would be useful only as a diagnostic A/B test: if function:ProcessGraphMailNotification = 1 immediately makes queue processing work, that would strongly suggest the runtime binding itself is healthy and the failure is specifically in scale-from-zero detection/activation.

    For escalation, collect the Function App resource ID, Storage account/queue name, exact UTC timestamps when messages were present, Application Insights scale-controller logs, trigger-sync timestamp/result, and the current Flex configuration.

    Sharing you these references:

    Microsoft Learn – Flex Consumption plan and always-ready instances.

    https://learn.microsoft.com/en-us/azure/azure-functions/flex-consumption-plan?

    Microsoft Learn – Event-driven/per-function scaling.

    https://learn.microsoft.com/en-us/azure/azure-functions/event-driven-scaling?

    Microsoft Learn – Functions deployment and trigger synchronization.

    https://learn.microsoft.com/en-us/azure/azure-functions/functions-deployment-technologies?

    Microsoft Learn – Scale-controller logging.

    https://learn.microsoft.com/en-us/azure/azure-functions/configure-monitoring?

    I would frame this as “host metadata is healthy, but Flex scale-from-zero activation for the private queue trigger appears not to be occurring” rather than as a confirmed .NET 10 issue.

    Please "Accept the Answer" if this information helped you. This will help us and others in the community as well.

    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.