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
- 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?
- Is an explicit
syncfunctiontriggers call expected or recommended after deploying a Flex Function App using private networking/VNet integration?
- 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.
- 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?
- 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
-
- 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?
- 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?
- Is there specific scale-controller telemetry available to show why
function:ProcessGraphMailNotification is not being instantiated?
- Is an always-ready instance expected/required for this combination, or should normal event-driven scale-from-zero work?
- 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