Direct Routing - routing outbound calls based on SBC rather than dialled number...

Occasional Contributor



This is a bit old fashioned but we have 3 SBCS connected to Microsoft Phone System within our Teams Admin Centre / O365 tenant and we are trying to shape our outbound voice routing policies to simply try SBC#1 and SBC#2 in that order, rather than looking at the dialled number to decide which SBCS to use.


It appears that MS Phone System outbound routing policies (what I would usually call trunks and trunk groups in PBX language) don't really allow for this. It feels like the only priority ordering exists for all policies together, when we want to put a user in a policy that simply tries 1 of 2 SBCs geographically local to them and nothing else.


Am I just looking at this all wrong or is there a way to simply shape a Policy to try 1 SBC then another regardless of what number they dial?


Currently we simply look for .* as the dialled number and pass it through to the SBC and then the SBC shapes the call accordingly. This works fine for us, but whatever we do, we cannot get it to try the second SBC if the first one is taken administratively offline....



7 Replies
best response confirmed by ThereseSolimeno (Microsoft)

@solidpro Each of your SBCs needs its own PSTN Usage and Voice Route, and each of your PSTN usages must be ordered in your desired routing manner within your voice policies.  You cannot combine all SBCs into a single PSTN usage and single voice route within a single voice policy, otherwise you will have the scenario you are experiencing.


The voice policy defines the Class of Service your users are allowed to call & outbound routing paths/failover. Your PSTN Usage and Voice Routes work to define number types and class of service, plus egress routing paths (including ordered failover) to your PSTN gateways. Proper design gets you a configuration that looks similar to below


AllEnterprise-NANPA (Voice Policy):

PSTN UsageVoice RoutePSTN Gateway


Outbound routing in the Teams/Skype world is firstly based of dialed digits, so your voice routes need to have some level of matching of DNIS for the call to work. If you are using wildcard (.*) then simply having unique voice policies for your specific use cases, along with ordered PSTN Usages and Voice Routes will get you what you want.


All that being said, I am not a fan of wildcard routes and I generally never advise customers to deploy in that manner. It's the "easiest method" but it also does not allow for any separation of class of service for calls and potentially allows calls to number types which you do not want (9XX, for instance). You should also be normalizing all numbers into E.164 format in your dial plans and structuring voice routing configuration based on E.164 concepts. If you don't need to break out things like local dialing restrictions, or mobile dialing restrictions, or premium number dialing restrictions, then you would not need a wildly complex routing configuration. Regardless, I strongly suggest you have all configuration utilizing E.164 from dial plans, to voice routes, to trunk translations, as that is the way a proper design should be.


Very few items have changed since the Lync days, as the concepts are largely still the same for Teams (basically brought forward). If you need to gain a better understanding, check out these videos or get in contact with a voice partner that can assist you.


@Trevor Miller thank you for taking the time to write a detailed response.


I agree, that the wildcard .* is very inflexible, but we have a really simple setup with no need for any restrictions, no physical handsets and no need to route calls based on destination number.


So we have put each SBC into it's own PSTN Usage and Voice Route and then created 2 policies - one for East coast users and one for west coast users. This works fine when a user is in a policy with 1 route/1 Usage/ 1 SBC.


However if we add the second route in the policy or a second usage in the route, the calls *never* use the second SBC. We tried changing the ordering as well as disabling the primary route at the SBC itself (either via it's trunk to MSPBX or it's external/public IP address) - it never goes to the second SBC.


We can remove the first and only THEN does either the route or the policy use the other/alternate SBC.


So is this something that is just 'broken'!? Thank you!




Examples First:


If you want both SBCs to be utilized for calls within a single "Class of Service", you'd have a voice policy that has a single PSTN Usage assigned:

PSTN UsageVoice RoutePSTN Gateway

In this instance, Outbound Routing should Round-Robin the calls to each PSTN Gateway assigned to the Voice Route. Effectively no ordering here and operates more of a HA pair for all SBCs in the Voice Route.


If you want ordered failover for calls within a single "Class of Service", you'd have a voice policy that has two PSTN Usage assigned:

PSTN UsageVoice RoutePSTN Gateway


In this instance, Outbound Routing will NEVER attempt to route to the second PSTN usage unless the first path is deemed "Offline". This could be SIP OPTIONS pings failing or certain SIP 5XX response failures, but there is explicit ordering here that will always use the first path and only use that path until a failure occurs.


Testing recommendations:

  • After any change is made in the Admin Center or through Voice Routing, you need to wait at least 15 minutes. There are notorious replication delays within M365 so do not make a change and then immediately make a call - chances are your changes are not yet effective within the service.
  • After your 15 minute waiting period, you need to sign-out and sign-in within the Teams app. The app itself uses caching to handle offline scenarios and improve general performance, so do not make a change and then immediately make a call - chances are your changes are not yet effective on the client.


SBC Notes:

  • The SIP failure an SBC will provide when it cannot route a call to an upstream peer (either SIP or T1/E1 related) varies with each vendor and reason for upstream failure. If a call from Teams reaches the SBC and the SBC has nowhere to send it, you must look at the SIP Call Ladder post-call to determine what failure is being sent back to Teams. If that failure is not a 5XX level failure, Outbound Routing in Teams may not attempt to find another route. This may require SIP manipulations on the SBC to "fix".
  • Make sure you are using an approved SBC vendor and that you are running at least the minimum firmware required for Direct Routing. Anything outside of that list is just futility and is a waste of your time.


Your desire for ordered SBC usage is absolutely possible - The service supports it and we've deployed as such many, many times. 

@Trevor Miller 


Thanks again.


We did exactly as you suggested - "voice policy that has two PSTN Usage" and virtually the same as you described, and it never failed over to the other one. Although the difference was we didn't wait at least 15 minutes.... Maybe it's best to try again....


"The SIP failure an SBC will provide when it cannot route a call " - in our testing we take the primary SBC out of service altogether - the SBC is entirely offline and there is no response to it's FQDN whatsoever - so in this case there would not be a response whatsoever from the SBC to route the call. Specifically this testing is not proving that the SBC sends the correct information back that no route is available or for the SBC to find alternate onward routes, it's for MS Phone System to seek out a different SBC when making an outbound call when the primary is not available whatsoever...


These are Ribbon SBCs so they definitely qualify...

@Trevor Miller 


Hi - could you help me confirm one detail? If we are to attempt this in TAC rather than powershell, I believe your second suggestion "If you want ordered failover for calls within a single "Class of Service", you'd have a voice policy that has two PSTN Usage assigned" is achieved within TAC under Voice / Voice Routing Policy / Click on the policy and then add a second PSTN usage record - is this correct?


We are going to test this on Monday, followed by a 20 minute tea break and logout and in of apps...





@Trevor Miller 


Hi. We tested it and it worked, but with a limitation.


When adding the second PSTN usage to the policy, if the Primary SBC was alive, but no routes were available to carry the call onward to the PSTN, the SIP messaging is sent back to MS PBX from the Primary SBC to try the second PSTN Usage and SBC. In this scenario, the fallback worked and the call routed over the second SBC.


However if the primary SBC is not responding whatsoever. I.E. is completely offline, the fail over does not occur. MSPBX simply tries the primary PSTN usage forever. 


This was tested after 30 minutes and signing in and out. This proves the VRP is able to fail over to a backup usage upon receiving a 'no route available' or similar message back from the primary SBC, but does not work when the primary does not respond at all.


Is this a bug, limitation or something that could be resolved by further configuration?



There are several ways in which outbound routing will attempt to find another path due to SBC "outage":

  • Sip Options Failure
  • 10 second 18X timer
  • SIP Failover Response Code


During your testing, did you see the SBC reported as offline in the Admin Center (Voice>Direct Routing>SBCs)? If the SBC was truly offline (from the perspective of Microsoft), you should see the TLS connectivity status and SIP options status showing "Inactive" and "Warning".


If the outbound routing re-route is working with a SIP Response Code (this was your scenario where there was no trunk available from the PSTN), it should work in scenario where the entire SBC is "offline". 

  1. Make sure the -SendSipOptions and -FailoverTimeSeconds parameters are enabled on your CsOnlinePstnGateway object for your SBCs.
  2. Make sure you are using separate and unique FQDNs/IPs for each of your SBCs. You cannot share a single FQDN/IP across multiple SBCs in geographically disperse data centers.
  3. Make sure your SBC is truly offline and has zero alternative Layer-3 network routes to reach M365. If your SBC is multi-homed (which it should be if it is deployed on-premises), you need to make sure that Options requests aren't somehow routing out another NIC to M365, and making it look "up" when it should be down.
  4. Try disabling the SBC in Direct Routing through the -Enabled $False param instead of manipulating the SBC in the data center.


Would strongly suggest opening an M365 support incident and/or involve a Ribbon partner to troubleshoot further. Something tells me you're still missing configuration, either on the SBC or within Direct Routing.