What are the exact commands to reproduce this bug? As I read _create_qos_rules() I'm quite sure there is a problem here, but I can't seem to find how to reproduce it. This succeeds for me: openstack network qos policy create qp0 openstack network qos rule create --type bandwidth-limit --max-kbps 1000 qp0 openstack port create port0 --network private openstack port set port0 --qos-policy qp0 And this too: openstack network qos policy create qp0 openstack port create port0 --network private openstack port set port0 --qos-policy qp0 On the other hand I found this to fail: openstack network qos policy create qp0 openstack network qos rule create --type bandwidth-limit --max-kbps 1000 qp0 openstack port create port0 --network private --qos-policy qp0 But this one fails with KeyError: 'qos_burst': febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers [None req-4c0f75c2-b509-43db-af4b-49c072229a67 admin admin] Mechanism driver 'ovn' failed in create_port_postcommit: KeyError: 'qos_burst' febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers Traceback (most recent call last): febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers File "/opt/stack/neutron/neutron/plugins/ml2/managers.py", line 475, in _call_on_drivers febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers getattr(driver.obj, method_name)(context) febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers File "/opt/stack/neutron/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py", line 530, in create_port_postcommit febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers self._ovn_client.create_port(port) febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers File "/opt/stack/neutron/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py", line 418, in create_port febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers port, lswitch_name) febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers File "/opt/stack/neutron/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py", line 718, in _create_qos_rules febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers burst=int(qos_options['qos_burst']), febr 12 16:28:08 devstack0 neutron-server[8429]: ERROR neutron.plugins.ml2.managers KeyError: 'qos_burst' Reading the relevant code... https://opendev.org/openstack/neutron/src/commit/a026b39617f4c2d29f2903909fb65f7adb327fa7/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py#L701-L729 https://opendev.org/openstack/neutron/src/commit/a026b39617f4c2d29f2903909fb65f7adb327fa7/neutron/services/qos/drivers/ovn/driver.py#L117-L136 https://opendev.org/openstack/neutron/src/commit/a026b39617f4c2d29f2903909fb65f7adb327fa7/neutron/services/qos/drivers/ovn/driver.py#L97-L115 https://opendev.org/openstack/neutron/src/commit/a026b39617f4c2d29f2903909fb65f7adb327fa7/neutron/objects/qos/rule.py#L127-L141 ... it is clear that _create_qos_rules() should be more careful with what's in qos_options since according to the OVO definition max_kbps and max_burst_kbps are optional. (Side question: What is a bandwidth limit rule without max_kbps?!) To my understanding of OVO even the defaulted fields may not be present unless we call .obj_set_defaults() on the rule object. So _create_qos_rules should not make these assumptions: * that qos_options['direction'] exists, line 704 * that qos_options['qos_burst'] exists, line 718 For qos_options['direction'] alternatively we may do something like this (did not test this yet) since this would make the defaulted rule fields actually present for all users of qos rule objects: neutron/objects/qos/rule.py class QosRule(base.NeutronDbObject): + def obj_load_attr(self, attrname): + self.obj_set_defaults(attrname)