Azure IoT Hub Routing: Message Matching Event Grid Route Also Reaching Built-in Endpoint When Fallback Route Is Enabled

Sandeep Sureshkumar 0 Reputation points
2026-08-21T11:13:29.71+00:00

I'm trying to understand the behavior of Azure IoT Hub message routing and whether what I'm observing is expected.

IoT Hub Configuration

I have two enabled routes:

Route 1: Event Grid Endpoint

routing query:

NOT(is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev"))

Destination: Event Grid

Route 2: Built-in Endpoint (events)

routing query:

is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev")

Destination: events (built-in endpoint)

Additionally:

Fallback Route = Enabled

Messages Sent
Message: 1

appTopic = rt.test/dev/300000-1cf6-4fa1-a4d5-14da294cdf53

Message: 2

appTopic = rt.test/fnd/300000-1cf6-4fa1-a4d5-14da294cdf53

Expected Behavior

Based on the routing queries:

Message 1: should match

is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev")

and be routed to: Built-in endpoint (events)

Message 2: should match

NOT(is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev"))

and be routed to: Event Grid

Actual Behavior Observed

With Fallback Route Enabled

Event Grid Trigger Function

Receives only:

  • appTopic = rt.test/fnd/300000-1cf6-4fa1-a4d5-14da294cdf53,

which is expected.

Event Hub Trigger Function (reading from built-in endpoint)

Receives:

  • appTopic = rt.test/fnd/300000-1cf6-4fa1-a4d5-14da294cdf53
  • appTopic = rt.test/dev/300000-1cf6-4fa1-a4d5-14da294cdf53

The second message (rt.test/fnd/...) is unexpectedly arriving at the built-in endpoint as well.

With Fallback Route Disabled

Event Grid Trigger Function

Receives only: appTopic = rt.test/fnd/300000-1cf6-4fa1-a4d5-14da294cdf53

Event Hub Trigger Function

Receives only: appTopic = rt.test/dev/300000-1cf6-4fa1-a4d5-14da294cdf53

This is the behavior I originally expected.

Question ?

Why is the message with:

appTopic = rt.test/fnd/300000-1cf6-4fa1-a4d5-14da294cdf53

being delivered to both Event Grid and Built-in endpoint (events) when the fallback route is enabled?

Since the message clearly matches the Event Grid route, I would expect it not to be treated as an unmatched message.

Is this:

  1. Expected behavior of the IoT Hub built-in endpoint and fallback routing?
  2. A special behavior specific to the built-in events endpoint?
  3. An undocumented limitation?
Azure Event Grid
Azure Event Grid

An Azure event routing service designed for high availability, consistent performance, and dynamic scale.

0 comments No comments

1 answer

Sort by: Most helpful
  1. Allan Solomon Mejia 7,995 Reputation points
    2026-08-21T16:21:59.6533333+00:00

    Hello @Sandeep Sureshkumar

    What you're observing is understandable, but there is an important distinction between IoT Hub message routing to the built-in endpoint and IoT Hub → Event Grid integration.

    Your two queries themselves are mutually exclusive:

    Event Grid:

    NOT(is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev"))

    Built-in events:

    is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev")

    So, based purely on normal IoT Hub routing, rt.test/fnd/... should match only the first condition, while rt.test/dev/... should match only the second.

    However, Event Grid integration works differently than a normal custom message-routing endpoint.

    When you create an Event Grid subscription for Microsoft.Devices.DeviceTelemetry, IoT Hub creates a default route named RouteToEventGrid based on that subscription. Microsoft specifically documents that if you want to filter telemetry before it's published to Event Grid, you modify that routing query.

    The built-in events endpoint and fallback routing have another behavior worth noting. Microsoft documents that once custom routes exist, messages only reach the built-in endpoint through an explicit route to events or through the fallback mechanism. The fallback route is intended for messages that don't match another applicable message route.

    In a standard routing configuration, a message can also match multiple routes. If it does, IoT Hub sends it to each associated endpoint; it only deduplicates when multiple matching routes have the same destination.

    That makes your A/B test particularly useful:

    Fallback disabled

    rt.test/dev/... → built-in endpoint

    rt.test/fnd/... → Event Grid

    This is exactly what your routing conditions imply.

    Fallback enabled

    rt.test/dev/... → built-in endpoint

    rt.test/fnd/... → Event Grid + built-in endpoint

    The second result isn't what I'd expect from the documented definition of fallback routing if rt.test/fnd/... has successfully matched RouteToEventGrid. Microsoft describes fallback as handling messages that don't match any routes when fallback is enabled.

    So I wouldn't explain this simply as "fallback always sends a copy to the built-in endpoint." That's not the documented behavior.

    What I would check

    First, go to: IoT Hub → Message routing → Routes

    and verify the actual route generated for Event Grid, particularly the route named something similar to: RouteToEventGrid

    Confirm that the condition there is exactly: NOT(is_defined(appTopic) AND starts_with(appTopic, "rt.test/dev"))

    Also use the Test route with both sample messages. Microsoft provides this specifically for verifying whether a message matches a routing query.

    I'd also check the IoT Hub routing metrics, especially Routing Deliveries and related routing metrics. Microsoft recommends these when diagnosing whether messages matched routes, were delivered, or were handled by fallback.

    If the route tester/metrics confirm rt.test/fnd/... matches RouteToEventGrid, but enabling fallback still causes an additional copy to appear on $Default/events, then I think you've isolated behavior that deserves investigation by the IoT Hub team.

    Your test is actually quite strong because changing only the fallback setting changes whether the duplicate reaches the built-in endpoint.

    I would provide Microsoft Support with the IoT Hub name/region, Event Grid subscription, RouteToEventGrid configuration, timestamps/message IDs, routing metrics, and the two test results showing fallback enabled versus disabled.

    Sharing these references with you:

    Microsoft - Azure IoT Hub and Event Grid

    Microsoft - Understand IoT Hub message routing

    Microsoft - Troubleshoot Azure IoT Hub message routing

    So, based on Microsoft's documented routing semantics, I wouldn't consider the duplicate delivery to events automatically expected simply because fallback is enabled. If the Event Grid route genuinely matched the message, fallback shouldn't normally be required for that message. Your fallback-on/off reproduction is worth escalating if the route tester confirms the match.

    Help make this community better for everyone: if this answer resolved your issue, please accept it or leave an upvote. If not, share more details in a comment so we can continue the discussion and find the right solution.

    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.