Hi Nate, We did have a chat on #neutron yesterday [1], but let me summarize my thoughts here for a broader audience and add some details I tried since: Let me differentiate three API workflows: A) workflow 1) in order: * create net and subnet for parent port * create parent port (more precisely a port that will become a parent port in the next step) * create trunk with parent port (and optionally subports) * boot vm with parent port (server create --nic port-id=) side note: Neither the trunk, nor subports should ever be passed to 'server create'. Nova only ever knows about the parent port. Generally nova does not treat this port specially in any way, except for ovs, where (based on what neutron tells nova in port attributes) nova plugs the vif into a trunk bridge instead of br-int. In this case the parent port existed before nova ever learned about it, therefore nova does not want to delete it when deleting the server. As with other use cases where a port needs to be somehow special, but we did not want to change nova to support it, this is the canonical way to use trunk ports. Here you lose the convenience of '--nic net-id='. And you lose some flexibility by not (always) being able to turn a plain old port into a trunk parent. I think the bug is not present when using this workflow so this is a possible workaround. workflow 2) * create net and subnet * boot vm with network (server --nic port-id=) * delete vm Here no trunk is created at all, so the bug is obviously not present. I just wanted to mention that in this case, nova creates the port for the server and it also wants to delete the port when deleting the server. Originally I think we considered this as unsupported (for trunks), and that not being a problem since it is only for convenience. workflow 3) in order: * create net and subnet * boot vm with net (server create --nic net-id=) * find the port nova created * create trunk with port found as parent (and optionally subports) * delete the vm This workflow reproduces (part of) the bug. Please see [2] for exact commands. Not all (ml2+trunk) drivers allow trunk creation on an already bound port. Here I used ovn which allows it, but ovs would not. While we may consider this a bug, and fix it, please note that the error would not occur if a port had been pre-created. IIRC we considered the ability to turn a bound port into a trunk parent a feature, but we considered the use of '--nic net-id=' only a convenience. Obviusly we may argue that we lost some flexibility since the user must create this port before boot and before he may have realized he wanted a trunk. B) The bug report mentions a "second interface", which never happens even in workflow 3) above. So I suspect there's something else going on beyond workflow 3). I have no proof but a hunch that the API is used in some way that it is not supposed to. Unfortunately the trunk API is not (and could not be made) intuitive and some important error conditions are silent, because of the enormous work they would have entailed. One such situation I see quite frequently is that people try to add subports to a server boot. But that is not needed and should never be done. That is an error but unfortunately with no immediate error message. But this is just based on a hunch. It still would be nice to know what actual API workflow led to the errors reported in the bug. I'd be happy to review it and incorporate the learnings into our docs. Cheers, Bence [1] http://eavesdrop.openstack.org/irclogs/%23openstack-neutron/%23openstack-neu... [2] https://etherpad.opendev.org/p/lp-1878031