11-12-2025 10:19 AM - edited 11-12-2025 10:28 AM
Im running into a unique issue with the genie parser for the command show ip mroute summary vrf vrf_captain_america. The same parser works fine on my Nexus switches that are not part of the vxlan fabric, and I get the parsed output correctly.
However, when I use the same command on the Nexus model leaf or border leaf switches of my vxlan fabric, the command parsing fails. So I tried to run the parser through the pyATS cli and I see the following error.
Please can someone help me fix this parser issue.
pyats parse "show ip mroute summary vrf vrf_captain_america" --testbed-file intf_detail_testbed.yaml --output log_files/12Nov2025
Issue with the parser show ip mroute summary vrf vrf_captain_america
Traceback (most recent call last):
File "src/genie/cli/commands/parser.py", line 339, in genie.cli.commands.parser.ParserCommand.parse
File "src/genie/conf/base/device.py", line 536, in genie.conf.base.device.Device.parse
File "src/genie/conf/base/device.py", line 576, in genie.conf.base.device.Device._get_parser_output
File "src/genie/conf/base/device.py", line 574, in genie.conf.base.device.Device._get_parser_output
File "src/genie/metaparser/_metaparser.py", line 342, in genie.metaparser._metaparser.MetaParser.parse
File "src/genie/metaparser/_metaparser.py", line 322, in genie.metaparser._metaparser.MetaParser.parse
File "src/genie/metaparser/util/schemaengine.py", line 419, in genie.metaparser.util.schemaengine.Schema.validate
genie.metaparser.util.exceptions.SchemaMissingKeyError: Missing keys: [['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.20.32/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.20.33/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.48.40/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.48.87/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.49.1/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.49.2/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.49.3/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.49.4/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.56/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.57/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.60/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.113/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.126/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.150/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.151/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.153/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.65.187/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.40/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.41/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.42/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.43/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.44/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.45/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.46/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.50/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.51/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.52/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.53/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.54/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.55/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.80.56/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.40/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.41/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.42/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.43/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.44/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.45/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.46/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.50/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.51/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.52/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.53/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.54/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.55/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.56/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.208/32', 'source'], ['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.81.209/32', 'source']]
My current package list is as follows
Package Version
---------------------------- -------------
genie latest (25.9)
genie.libs.clean latest (25.9)
genie.libs.conf latest (25.9)
genie.libs.filetransferutils latest (25.9)
genie.libs.health latest (25.9)
genie.libs.ops latest (25.9)
genie.libs.parser latest (25.9)
genie.libs.sdk latest (25.9)
genie.trafficgen latest (25.9)
pyats latest (25.9)
pyats.aereport latest (25.9)
pyats.aetest latest (25.9)
pyats.async latest (25.9)
pyats.connections latest (25.9)
pyats.contrib latest (25.9)
pyats.datastructures latest (25.9)
pyats.easypy latest (25.9)
pyats.kleenex latest (25.9)
pyats.log latest (25.9)
pyats.reporter latest (25.9)
pyats.results latest (25.9)
pyats.tcl latest (25.9)
pyats.topology latest (25.9)
pyats.utils latest (25.9)
rest.connector latest (25.9)
unicon latest (25.9)
unicon.plugins latest (25.9)
yang.connector latest (25.9)
the command output from the device for one of the multicast group looks like this.
leaf_switch-5a# sh ip mroute 239.216.15.1 vrf vrf_captain_america | json-pretty
{
"TABLE_vrf": {
"ROW_vrf": {
"vrf-name": "vrf_captain_america",
"TABLE_one_route": {
"ROW_one_route": {
"mcast-addrs": "(10.110.15.1/32, 239.216.15.1/32)",
"source_addrs": "10.110.15.1/32",
"group_addrs": "239.216.15.1/32",
"pending": "false",
"bidir": "false",
"uptime": "2y21w",
"uptime_detailed": "P2Y5M6DT7H45M25S",
"mofrr": "false",
"TABLE_mpib": {
"ROW_mpib": [
{
"mpib-name": "ip",
"stale-route": "false"
},
{
"mpib-name": "pim",
"stale-route": "false"
},
{
"mpib-name": "mrib",
"stale-route": "false"
}
]
},
"route-iif": "Vlan1011",
"rpf-nbr": "10.110.15.1",
"mofrr-iif": "Null",
"mofrr-nbr": "0.0.0.0",
"internal": "true",
"oif-count": "0",
"fabric-oif": "false",
"fabric-loser": "false"
}
}
}
}
}
11-12-2025 11:14 AM
@Akshayrane i guess the differences in the command output format between your non-VXLAN and VXLAN Nexus ones for the summary command. This is why you see the missing schema key error in your trackback error, and failed to find a mandatory sub-key named “source” in the structure which is defined for those groups in the parsers schema.
So I’m thinking two options. Either create and issue on the repo and request a parser or this one to be extended, but this will of course take time. Door number two, you can look to create a custom parser would inherit from the existing one and modifies the schema or the cli method to help handle the missing key when the output is from a VXLAN device.
Hope this helps.
11-13-2025 02:41 AM
@bigevilbeard Thanks for the suggestions. I found a few more things that may help. these findings dont really convince me to create a own parser based on the lines of the existing one.
1. The vxlan switch has 3 vrfs default, vrf_captain_america, vrf_black_widow. The non vxlan switch only has the default vrf. The issue is reported only for the vxlan switch vrf vrf_captain_america, the same parser works fine for vrf vrf_black_widow and vrf default on the same switch having the vrf vrf_captain_america like it does for the non vxlan switch.
2. the output of the show ip mroute summary vrf vrf_captain_america is similar to the all the other vrfs of the vxlan and the non vxlan switch. so the parser seems to be correct and it should work across vxlan and non vxlan environemnt. I also checked the parser schema and the parser regex at the location of the github repo genieparser/src/genie/libs/parser/nxos/show_mcast.py and foudn the parser regex is correctly configured to include the command output from the vxlan and the nonvxlan environments.
3. I then looked in detail at the output of the parser exception reported by the genie cli parser, it complained of a few multicast groups missing keys (genie.metaparser.util.exceptions.SchemaMissingKeyError: Missing keys) and checked them on the switch by running the show ip mroute summary vrf vrf_captain_america command and found no difference between the other multicast from different vrfs like default and vrf_black_widow. That concludes the switch does not have a different output for the command from the vrf vrf_captain_america to output from the other vrfs.
4. the vxlan and non vxlan switches are the same nexus model and run the same nxos version.
5. I also tested it on another nexus switch that is not the same model as the others and still no luck.
6. I also tested it on another nexus switch with a higher nxos version and the problem continues for the vrf vrf_captain_america across the vxlan fabric switches.
7. Ive now created a tac case to have this checked. Hopefully, they can help find something.
Any help till then is welcomed.
11-13-2025 03:05 AM
@Akshayrane nice work! So this would point to your issue is not a general parser flaw but something unique to the multicast state within your vrf captain america then, this is based on the info this works on default and black widow, but yet breaks as you noted this CLI looks similar to the others, so is this a subtle variation in the output format for specific multicast entries only there in captain america?
This is the root of your error i think
genie.metaparser.util.exceptions.SchemaMissingKeyError: Missing keys: [['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.20.32/32', **'source'**], ...]
But why is the question, something is going to be a slightly different format than what the parser's regex is set up to handle, causing it to skip the extraction of the source/group pair entirely, which then results in the mandatory 'source' key being missing. Can you share the vrf outputs (show ip mroute summary vrf vrf_captain_america / black_widow), understand if you cannot..
Let me know what TAC says, i am really interested in the outcome here.
11-13-2025 05:10 AM
@bigevilbeard yes it is completely weird! i tried to check for subtle differences but have found none.
the script reports exception for the vrf vrf_captain_america as follows, where i think it reports the following multicast may be missing the source fields in the show ip mroute summary vrf vrf_captain_america output. Lets take the multicast group 239.216.15.1 as an example. However, it is not as you can see the output of the command for the multicast group 239.216.15.1.
genie.metaparser.util.exceptions.SchemaMissingKeyError: Missing keys: [
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.1/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.2/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.3/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.4/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.6/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.8/32', 'source'],
['vrf', 'vrf_captain_america', 'address_family', 'ipv4', 'groups', '239.216.15.11/32', 'source'],
]
######## Output of the show ip mroute summary vrf vrf_captain_america for the group 239.216.15.1 ########
Group: 239.216.15.1/32, Source count: 1
Source packets bytes aps pps bit-rate oifs
10.132.15.1 179929117874 244703600308636 1359 2405 26.173 mbps 0
Compare the above output to a non vxlan switch vrf default for a group
######## Output of the show ip mroute summary vrf default for the group 239.209.128.26 ########
Group: 239.209.128.26/32, Source count: 1
Source packets bytes aps pps bit-rate oifs
10.145.63.0 2895442 147667542 51 0 27.200 bps 1
11-13-2025 05:27 AM
@Akshayrane this continues to get more interesting. I ran a diff (as i dont trust my eyes these days!) on both your structures and they are identical, so this would mean the failure is happening inside the parser's logic after the initial line by line matching, and it is somehow being triggered by something else unique about the data itself, or maybe an unexpected state change in the parser's internal loop (guessing here).
11-13-2025 05:44 AM - edited 11-13-2025 05:45 AM
the following is the actual command output from the vxlan and non vxlan switch alongwith the parser and the parser schema. Everything looks the same. So data from the switch that is being parsed upon is fine.
I also tried to disable the parser schema check in my script when i parse the command but no luck the execution fails
show_ip_mroute_summ_vrf_vrfname_cmd_op = device_object.parse("sh ip mroute summary vrf vrf_captain_america", include_schema=False)
######## Output of the show ip mroute summary vrf vrf_captain_america for the group 239.216.15.1 from the vxlan switch ########
leaf-switch-5a# sh ip mroute summary vrf vrf_captain_america
IP Multicast Routing Table for VRF "vrf_captain_america"
Route Statistics unavailable - only liveness detected
Total number of routes: 1570
Total number of (*,G) routes: 748
Total number of (S,G) routes: 821
Total number of (*,G-prefix) routes: 1
Group count: 852, rough average sources per group: 0.9
Group: 239.216.15.1/32, Source count: 1
Source packets bytes aps pps bit-rate oifs
10.144.15.1 179929117874 244703600308636 1359 2405 26.173 mbps 0
######## Output of the show ip mroute summary vrf default for the group 239.209.128.26 from the non vxlan switch ########
non-vxlan-switch# sh ip mroute summary vrf default
IP Multicast Routing Table for VRF "default"
Route Statistics unavailable - only liveness detected
Total number of routes: 1105
Total number of (*,G) routes: 4
Total number of (S,G) routes: 1100
Total number of (*,G-prefix) routes: 1
Group count: 920, rough average sources per group: 1.1
Group: 239.209.128.26/32, Source count: 1
Source packets bytes aps pps bit-rate oifs
10.145.63.0 2895442 147667542 51 0 27.200 bps 1
####### Parser and parser schema from the genieparser/src/genie/libs/parser/nxos/show_mcast.py #######
# ===================================
# Parser for 'show ip mroute summary vrf all'
# ===================================
class ShowIpMrouteSummarySchema(MetaParser):
"""Schema for show ip mroute summary vrf all"""
schema = {
'vrf': {
Any(): {
'address_family': {
Any(): {
'count_multicast_starg': int,
'count_multicast_sg': int,
'count_multicast_starg_prefix': int,
'count_multicast_total': int,
'group_count': int,
'avg_source_per_group': float,
'groups': {
Any(): {
'source_count': int,
'source': {
Any(): {
'packets': int,
'bytes': int,
'aps': int,
'pps': int,
'bitrate': float,
'bitrate_unit': str,
'oifs': int
},
},
}
},
},
}
},
}
}
class ShowIpMrouteSummary(ShowIpMrouteSummarySchema):
"""parser for:
show ip mroute summary
show ip mroute summary vrf <vrf>
show ip mroute summary vrf all"""
cli_command = ['show ip mroute summary vrf {vrf}',
'show ip mroute summary']
def cli(self, vrf="default", output=None):
if vrf != 'default':
cmd = self.cli_command[0].format(vrf=vrf)
else:
cmd = self.cli_command[1]
if output is None:
out = self.device.execute(cmd)
else:
out = output
mroute_dict = {}
#IP Multicast Routing Table for VRF "vxlan-1001"
p1 = re.compile(r'^\s*(?P<address_family>[\w\W]+) [mM]ulticast'
r' +[rR]outing +[tT]able +for +VRF '
r'+(?P<vrf>\S+)$')
# Total number of (*,G) routes: 34
p2 = re.compile(r'^\s*Total +number +of +\(\*,G\) +routes:'
r' +(?P<count>[0-9]+)$')
# Total number of (S,G) routes: 17
p3 = re.compile(r'^\s*Total +number +of +\(S,G\) +routes:'
r' +(?P<count>[0-9]+)$')
# Total number of routes: 51
p4 = re.compile(r'^\s*Total +number +of +routes:'
r' +(?P<count>[0-9]+)$')
#Total number of (*,G-prefix) routes: 0
p5 = re.compile(r'^\s*Total +number +of +\(\*,G-prefix\) +routes:'
r' +(?P<count>[0-9]+)$')
#Group count: 41, rough average sources per group: 3.0
p6 = re.compile(r'^\s*Group +count: +(?P<count>[0-9]+),'
r' +rough +average +sources +per +group: +(?P<avg_count>[0-9.]+)$')
#Group: 225.0.0.2/32, Source count: 3
p7 = re.compile(r'^\s*Group: +(?P<group_ip>\S+), +Source count: +(?P<src_count>[0-9]+)$')
#100.100.100.5 1743 88893 51 0 27.200 bps 1
#(*,G) 0 0 0 0 0.000 bps 2
p8 = re.compile(r'^\s*(?P<source>\S+) +(?P<packets>[0-9]+) +(?P<bytes>[0-9]+) +(?P<aps>[0-9]+) +(?P<pps>[0-9]+) +'
r'(?P<bitrate>[0-9.]+) +bps +(?P<oifs>[0-9]+)$')
for line in out.splitlines():
line = line.strip()
m = p1.match(line)
if m:
vrf = m.groupdict()['vrf']
vrf = vrf.replace('"',"")
address_family = m.groupdict()['address_family'].lower()
address_family += 'v4'
address_family_dict = mroute_dict.setdefault('vrf', {}).setdefault(vrf,{}).setdefault('address_family', {}).setdefault(address_family, {})
continue
m = p2.match(line)
if m:
count_multicast_starg = m.groupdict()['count']
address_family_dict.setdefault('count_multicast_starg', int(count_multicast_starg))
continue
m = p3.match(line)
if m:
count_multicast_sg = m.groupdict()['count']
address_family_dict.setdefault('count_multicast_sg', int(count_multicast_sg))
continue
m = p4.match(line)
if m:
count_multicast_total = m.groupdict()['count']
address_family_dict.setdefault('count_multicast_total', int(count_multicast_total))
continue
m = p5.match(line)
if m:
count_multicast_starg_prefix = m.groupdict()['count']
address_family_dict.setdefault('count_multicast_starg_prefix', int(count_multicast_starg_prefix))
continue
m = p6.match(line)
if m:
address_family_dict.setdefault('group_count', int(m.groupdict()['count']))
address_family_dict.setdefault('avg_source_per_group', float(m.groupdict()['avg_count']))
continue
m = p7.match(line)
if m:
group_ip = m.groupdict()['group_ip']
source_count = m.groupdict()['src_count']
group_dict = address_family_dict.setdefault('groups',{}).setdefault(group_ip,{})
group_dict.update({'source_count': int(source_count)})
continue
m = p8.match(line)
if m:
src_dict = group_dict.setdefault('source',{}).setdefault(m.groupdict()['source'],{})
src_dict.update({'packets': int(m.groupdict()['packets']),'bytes': int(m.groupdict()['bytes']),'aps': int(m.groupdict()['aps']),'pps': int(m.groupdict()['pps']),'bitrate': float(m.groupdict()['bitrate']),'bitrate_unit':'bps','oifs': int(m.groupdict()['oifs'])})
continue
return mroute_dict
11-13-2025 06:11 AM
@Akshayrane ok from this infro (great thanks!), this proves as you noted disabling the schema check doesnt fix this, because from what we have learnt the schema error is actually a symptom of the parser logic failing and looks to fail when it goes to create the nedded dictionary structure in the first place.
So... I ran this over and from what i get back, the line of code src_dict = group_dict.setdefault('source',{})...
Looking at the output here, If the parser encounters a line that matches p8 before, matching a p7 line in the current output loop (or if p7 fails to match for some internal reason), the var group_dict is not defined, causing the unbound local error. This however does not answer why capatin america fails tho!
Its breaking in the regex somehow, either hidden entries before the first standard group line or between, p8 matches unexpectedly, i am wild guessing here tho again. In your code, you could try by initialising your group_dict (set this to = None) before the loop and adding a quick check before accessing it?
11-13-2025 06:20 AM
the snippet of the code is actually from the genie parser github repo. it is not my script. in my script i just use the parser as follows in a try-except block.
11-13-2025 06:55 AM
@Akshayrane can you show me the outputs of default and black widow please - 'show ip mroute summary vrf [name]?
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide