mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-11 21:10:29 +01:00
Inconsistent data being returned from new dcim.mac_addresses endpoint #11400
Closed
opened 2025-12-29 21:44:40 +01:00 by adam
·
19 comments
No Branch/Tag Specified
main
update-changelog-comments-docs
feature-removal-issue-type
20911-dropdown
20239-plugin-menu-classes-mutable-state
21097-graphql-id-lookups
feature
fix_module_substitution
20923-dcim-templates
20044-elevation-stuck-lightmode
feature-ip-prefix-link
v4.5-beta1-release
20068-import-moduletype-attrs
20766-fix-german-translation-code-literals
20378-del-script
7604-filter-modifiers-v3
circuit-swap
12318-case-insensitive-uniqueness
20637-improve-device-q-filter
20660-script-load
19724-graphql
20614-update-ruff
14884-script
02496-max-page
19720-macaddress-interface-generic-relation
19408-circuit-terminations-export-templates
20203-openapi-check
fix-19669-api-image-download
7604-filter-modifiers
19275-fixes-interface-bulk-edit
fix-17794-get_field_value_return_list
11507-show-aggregate-and-rir-on-api
9583-add_column_specific_search_field_to_tables
v4.5.0
v4.4.10
v4.4.9
v4.5.0-beta1
v4.4.8
v4.4.7
v4.4.6
v4.4.5
v4.4.4
v4.4.3
v4.4.2
v4.4.1
v4.4.0
v4.3.7
v4.4.0-beta1
v4.3.6
v4.3.5
v4.3.4
v4.3.3
v4.3.2
v4.3.1
v4.3.0
v4.2.9
v4.3.0-beta2
v4.2.8
v4.3.0-beta1
v4.2.7
v4.2.6
v4.2.5
v4.2.4
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.11
v4.1.10
v4.1.9
v4.1.8
v4.2-beta1
v4.1.7
v4.1.6
v4.1.5
v4.1.4
v4.1.3
v4.1.2
v4.1.1
v4.1.0
v4.0.11
v4.0.10
v4.0.9
v4.1-beta1
v4.0.8
v4.0.7
v4.0.6
v4.0.5
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v3.7.8
v3.7.7
v4.0-beta2
v3.7.6
v3.7.5
v4.0-beta1
v3.7.4
v3.7.3
v3.7.2
v3.7.1
v3.7.0
v3.6.9
v3.6.8
v3.6.7
v3.7-beta1
v3.6.6
v3.6.5
v3.6.4
v3.6.3
v3.6.2
v3.6.1
v3.6.0
v3.5.9
v3.6-beta2
v3.5.8
v3.6-beta1
v3.5.7
v3.5.6
v3.5.5
v3.5.4
v3.5.3
v3.5.2
v3.5.1
v3.5.0
v3.4.10
v3.4.9
v3.5-beta2
v3.4.8
v3.5-beta1
v3.4.7
v3.4.6
v3.4.5
v3.4.4
v3.4.3
v3.4.2
v3.4.1
v3.4.0
v3.3.10
v3.3.9
v3.4-beta1
v3.3.8
v3.3.7
v3.3.6
v3.3.5
v3.3.4
v3.3.3
v3.3.2
v3.3.1
v3.3.0
v3.2.9
v3.2.8
v3.3-beta2
v3.2.7
v3.3-beta1
v3.2.6
v3.2.5
v3.2.4
v3.2.3
v3.2.2
v3.2.1
v3.2.0
v3.1.11
v3.1.10
v3.2-beta2
v3.1.9
v3.2-beta1
v3.1.8
v3.1.7
v3.1.6
v3.1.5
v3.1.4
v3.1.3
v3.1.2
v3.1.1
v3.1.0
v3.0.12
v3.0.11
v3.0.10
v3.1-beta1
v3.0.9
v3.0.8
v3.0.7
v3.0.6
v3.0.5
v3.0.4
v3.0.3
v3.0.2
v3.0.1
v3.0.0
v2.11.12
v3.0-beta2
v2.11.11
v2.11.10
v3.0-beta1
v2.11.9
v2.11.8
v2.11.7
v2.11.6
v2.11.5
v2.11.4
v2.11.3
v2.11.2
v2.11.1
v2.11.0
v2.10.10
v2.10.9
v2.11-beta1
v2.10.8
v2.10.7
v2.10.6
v2.10.5
v2.10.4
v2.10.3
v2.10.2
v2.10.1
v2.10.0
v2.9.11
v2.10-beta2
v2.9.10
v2.10-beta1
v2.9.9
v2.9.8
v2.9.7
v2.9.6
v2.9.5
v2.9.4
v2.9.3
v2.9.2
v2.9.1
v2.9.0
v2.9-beta2
v2.8.9
v2.9-beta1
v2.8.8
v2.8.7
v2.8.6
v2.8.5
v2.8.4
v2.8.3
v2.8.2
v2.8.1
v2.8.0
v2.7.12
v2.7.11
v2.7.10
v2.7.9
v2.7.8
v2.7.7
v2.7.6
v2.7.5
v2.7.4
v2.7.3
v2.7.2
v2.7.1
v2.7.0
v2.6.12
v2.6.11
v2.6.10
v2.6.9
v2.7-beta1
Solcon-2020-01-06
v2.6.8
v2.6.7
v2.6.6
v2.6.5
v2.6.4
v2.6.3
v2.6.2
v2.6.1
v2.6.0
v2.5.13
v2.5.12
v2.6-beta1
v2.5.11
v2.5.10
v2.5.9
v2.5.8
v2.5.7
v2.5.6
v2.5.5
v2.5.4
v2.5.3
v2.5.2
v2.5.1
v2.5.0
v2.4.9
v2.5-beta2
v2.4.8
v2.5-beta1
v2.4.7
v2.4.6
v2.4.5
v2.4.4
v2.4.3
v2.4.2
v2.4.1
v2.4.0
v2.3.7
v2.4-beta1
v2.3.6
v2.3.5
v2.3.4
v2.3.3
v2.3.2
v2.3.1
v2.3.0
v2.2.10
v2.3-beta2
v2.2.9
v2.3-beta1
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.6
v2.2-beta2
v2.1.5
v2.2-beta1
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.10
v2.1-beta1
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
v2.0-beta3
v1.9.6
v1.9.5
v2.0-beta2
v1.9.4-r1
v1.9.3
v2.0-beta1
v1.9.2
v1.9.1
v1.9.0-r1
v1.8.4
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.7.3
v1.7.2-r1
v1.7.1
v1.7.0
v1.6.3
v1.6.2-r1
v1.6.1-r1
1.6.1
v1.6.0
v1.5.2
v1.5.1
v1.5.0
v1.4.2
v1.4.1
v1.4.0
v1.3.2
v1.3.1
v1.3.0
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.7-r1
v1.0.7
v1.0.6
v1.0.5
v1.0.4
v1.0.3-r1
v1.0.3
1.0.0
Labels
Clear labels
beta
breaking change
complexity: high
complexity: low
complexity: medium
needs milestone
netbox
pending closure
plugin candidate
pull-request
severity: high
severity: low
severity: medium
status: accepted
status: backlog
status: blocked
status: duplicate
status: needs owner
status: needs triage
status: revisions needed
status: under review
topic: GraphQL
topic: Internationalization
topic: OpenAPI
topic: UI/UX
topic: cabling
topic: event rules
topic: htmx navigation
topic: industrialization
topic: migrations
topic: plugins
topic: scripts
topic: templating
topic: testing
type: bug
type: deprecation
type: documentation
type: feature
type: housekeeping
type: translation
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/netbox#11400
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @jseifeddine on GitHub (Jul 20, 2025).
Originally assigned to: @jseifeddine on GitHub.
Deployment Type
Self-hosted
NetBox Version
v4.3.4
Python Version
3.11
Steps to Reproduce
BUG: Total interfaces from
dcim.mac_addressesendpoint (count 7978) does not match total interfaces fromdcim.interfacesendpoint (count 8628)After having stumbled upon a bug present in
v4.1.5withIPAM, which I successfully reproduced here https://github.com/jseifeddine/netbox-ipam-bug/Realizing that it was fixed in latest version from v4.3.3 - we upgraded to the newest
v4.3.4- and now experiencing a very similar issue with the new MAC addresses objects on the newdcim.mac_addressesendpoint. (mac objects and endpoint introduced in v4.2.0)We use
pynetboxto maintain "synchronization" between devices and NetBox.Syncing interface information (Status, Description, IPs, speed, type, mac address etc)
Our sync script only makes changes when it needs to, doing a delta check before hand to figure out what in NetBox needs updating/deleting/creating.
IP addresses were an issue, as per the bug repository attached above - causing unnecessary operations.
That was fixed with IP addresses, but MAC addresses now have similar issues. I haven't yet been able to reproduce it exactly how I did with the IPAM repo above, but in our dev environment, which is a clone of production - I can see inconsistent data being returned from the
dcim.mac_addressesendpoint, here is the best way I can display that:NetBox v4.3.4
Running this script;
Expected Behavior
Consistent data from the new MAC Addresses endpoint
For example, correct interface counts derived from assigned_object
Observed Behavior
BUG: Total interfaces from dcim.mac_addresses endpoint (7978) does not match total interfaces from dcim.interfaces endpoint (8628)
@jseifeddine commented on GitHub (Jul 20, 2025):
ok, I've updated that repo, to include testing MAC address endpoint bugs and able to reproduce it.
Steps to reproduce
Output of running tests:
@jseifeddine commented on GitHub (Jul 20, 2025):
A workaround, use the
dcim.interfacesendpoint to get reliable mac address data@jseifeddine commented on GitHub (Jul 21, 2025):
Also, for completeness - I should also add - MAC Address changes are not logged against the interface, as one might expect., Since they appear under the interface the same way IP addresses do.
No MAC Address changes referenced on the interface, even though IP addresses are, surely this is an oversight ?
The only reference is Primary MAC Address updates (ID) on the interface itself

@DanSheps commented on GitHub (Jul 21, 2025):
As per the note above "repoduction steps", please provide reproduction steps using raw queries (nbshell python api, graphql, openapi, etc):
@jseifeddine commented on GitHub (Jul 21, 2025):
Similar results
RAW- I did already test that, sorry should of provided as well.find all the related code here;
ae5465f70fadd requests logging
146d3cf4bb@jseifeddine commented on GitHub (Jul 21, 2025):
test-macs-raw.loghttps://gist.github.com/jseifeddine/2077fde582b7079aa4175567f6cb3678
test-ipam-raw.loghttps://gist.github.com/jseifeddine/9724f9f6cc957e8e59ad596a3fb739e0
You will find the results at the bottom of each gist - the results from the requests made...
Everything required to replicate this BUG, with RAW requests or with pynetbox is in https://github.com/jseifeddine/netbox-ipam-bug
I've added request logging, which you can see when running:
./test-ipam-raw.pyor./test-macs-raw.py@DanSheps commented on GitHub (Jul 21, 2025):
@jseifeddine You are still not providing recreating steps for our team to follow. Please properly document step-by-step recreation steps for us to follow.
@jeremystretch commented on GitHub (Jul 21, 2025):
Please also ensure your reproduction steps do not require the use of pynetbox in any way. This ensures that we can isolate the API client as a potential source of unexpected behavior.
@jseifeddine commented on GitHub (Jul 22, 2025):
Thanks @DanSheps and @jeremystretch
I have provided everything that you have requested and more - ready to easily setup, run and reproduce - in the repository I've attached: https://github.com/jseifeddine/netbox-ipam-bug
This bug I've identified seems to only happen in certain conditions (lots of interfaces, exact same MAC addresses on multiple interfaces) - So, I set up a docker stack so one could easily reproduce the bug.
The repository simply;
NETBOX_VERSIONof your choosing; in the bug report I have specifiedv4.3.4.env.envfor authentication, runs ainsert_dummy_data.pyscript that will create, Dummy Site, Dummy Device Role, Dummy Manufacturer, Dummy Device Type, Dummy Device, 10,000 Dummy Interfaces, 20,000 IP Addresses assigned to those interfaces (2 distinct IPs each interface, interfaces having the same IP addresses), 10,000 MAC Addresses (interfaces have the same MAC Address)--
test-ipam.py<-- tests IPAM and MAC Address bug (Clearly identifying mac address bug withpynetbox)--
test-ipam-raw.py<-- tests IPAM and MAC Address bug (Clearly identifying mac address bug with RAW APIrequests)--
test-macs.py<-- tests IPAM and MAC Address bug (Clearly identifying mac address bug withpynetbox)--
test-macs-raw.py<-- tests IPAM and MAC Address bug (Clearly identifying mac address bug with RAW APIrequests)I've already run these tests, providing the RAW API scripts, and logs;
These logs show the RAW API
requests(NOTpynetbox) and the result of testing, which exposes theBUGI am submitting.test-macs-raw.loghttps://gist.github.com/jseifeddine/2077fde582b7079aa4175567f6cb3678test-ipam-raw.loghttps://gist.github.com/jseifeddine/9724f9f6cc957e8e59ad596a3fb739e0As result of the following (easily reproducible
Thanks
@jseifeddine commented on GitHub (Jul 22, 2025):
If you are unable to view the repository I have made, please find the below
Requests logs and result:
@jseifeddine commented on GitHub (Jul 22, 2025):
In summary
lots of interfaces, all with the same mac address - assigned to them.
Compare data from
http://localhost:8080/api/dcim/mac-addresses/?device_id=1andhttp://localhost:8080/api/dcim/interfaces/?device_id=1BUG: Total interfaces(assigned_object) from dcim.mac_addresses endpoint (992) does not match total interfaces from dcim.interfaces endpoint (1000)
@DanSheps commented on GitHub (Jul 24, 2025):
Hello @jseifeddine
I am unable to reproduce this. Here is what I have done:
interfaces = requests.get('http://127.0.0.1:8000/api/dcim/interfaces/', headers={'Authorization': 'Token 908d25811c1cced6fe893a34ca598026e8276946', 'Content-Type': 'application/json', 'Accept': 'application/json'}, params={'device_id': 565, 'limit':1001}).json().get('results')macs = requests.get('http://127.0.0.1:8000/api/dcim/mac-addresses/', headers={'Authorization': 'Token 908d25811c1cced6fe893a34ca598026e8276946', 'Content-Type': 'application/json', 'Accept': 'application/json'}, params={'device_id': 565, 'limit':1001}).json().get('results')len(macs)which gives me 1000Unfortunately, this is all consistent with what is expected.
In the future, please provide fully reproducable steps without the use of scripts and only the raw API queries required.
@jseifeddine commented on GitHub (Jul 25, 2025):
Thank you @DanSheps - I understand where you are coming from - however you didn't perform the steps to reproduce exactly, I think it all comes down to pagination.
You checked the interfaces' macs length < -- this was never in question, this is actually how I've worked around this bug
The
len(macs)was also always showing correctly. Not in question.What is wrong: The count of the macs 'assigned_object'
Try this, (PS. it's only reproducible when paginating - perhaps a vital clue to the issue)
Results:
In case your not convinced, all interfaces have primary_mac_address;
so you can conclude that ALL mac addresses are assigned, having assigned_object.
@jseifeddine commented on GitHub (Jul 25, 2025):
As we've just discovered;
It isn't reproducible IF NOT paginating
AND, lowering the limit per page, exasperates the issue
@jseifeddine commented on GitHub (Jul 25, 2025):
if you actually look at that
mac_interfaces(derived from assigned_object , from mac addresses endpoint)@jseifeddine commented on GitHub (Jul 25, 2025):
it's a simple problem, but it takes a little bit of scripting to reproduce it.
its the nature of the bug - i cannot give you one API request that will reproduce this bug.
You must follow the steps that I shared initially.
Thanks
@jseifeddine commented on GitHub (Jul 25, 2025):
Scenario recap:
1000 Interfaces
Each interface assigned the SAME MAC address (eg. sub-interfaces each sharing the same (parent's interface MAC) MAC address)
I've forked and fixed the code responsible for this bug. However, unsure if the changes I've made follows your guidelines and if it will cause other issues.
d7f3fe8b0aMy tests pass with commit;
with netbox main branch it get this;
As per your community guidelines:
Please note that our contribution policy requires that a feature request or bug report be approved and assigned prior to opening a pull requestI will await your acknowledgement and approval....
Some notes;
Looking at the implementation of the MACAddressViewSet in
netbox/dcim/api/views.py, the issue is that it's not properly handling pagination with the GenericRelation for MAC addresses.The problem is that when filtering MAC addresses by device_id, the API is not correctly handling the GenericRelation between interfaces and MAC addresses, causing duplicate MAC addresses to appear across pagination boundaries.
Also, it may be a problem is in the filter_device method of the MACAddressFilterSet class in
netbox/dcim/filtersets.pyThe issue is that when filtering by device_id, the code gets all interfaces for the device, then filters MAC addresses by those interfaces. However, it doesn't account for the fact that the same MAC address can be associated with multiple interfaces through the GenericRelation, causing duplicates in pagination.
The issue was that when paginating through the API results without .distinct(), some MAC addresses were being returned multiple times across different pages. Here's what was likely happening:
To summarize:
Without .distinct(): 1000 MAC addresses (with some duplicates) on 997 unique interfaces.
With .distinct(): 1000 unique MAC addresses on 1000 unique interfaces.
The fix implemented ensures that the API behaves correctly and returns each MAC address exactly once, regardless of pagination.
@DanSheps commented on GitHub (Jul 25, 2025):
Thank you for the detailed information @jseifeddine
Could you write a test to test the filterset for this condition (perhaps we don't need to use 1000 interfaces/mac addresses, just enough to encounter this issue)
I will need to validate this on my end.
@jseifeddine commented on GitHub (Jul 26, 2025):
OK,
here is my best effort, the tests corroborate my initial findings.
It would seem that I can only replicate the issue in the API, which would make sense - because I guess (without testing) the netbox front end component was showing consistent data.
043dc4cc96the
.distinct()that I applied earlier was addressing the symptoms and not root cause, I wasn't satisfied as you could imagine, so I investigated further, inspecting the SQL queries just to be sure.Key Findings:
Basic query vs FilterSet query are DIFFERENT:
Basic query: interface__device_id = 1 (simple join)
FilterSet query: interface__id IN (1, 2, 3, ..., 1000) (massive IN clause)
Both return 1000 results - so the duplication isn't at the SQL level
The FilterSet is using the filter_device method which:
Gets all interfaces for the device (device.vc_interfaces())
Creates a massive IN clause with all interface IDs
This is less efficient than a simple join
When you have many MAC addresses with the same value (like 18:2A:D3:65:90:2E), the ordering becomes non-deterministic for records with identical mac_address values. This can cause the same records to appear on multiple pages during pagination.
Lo and behold, we aren't ordering by
idas we probably should be?netbox/dcim/models/devices.pyProposed Fix:
bf38821efcInstead of just adding .distinct(), we should fix the ordering to be deterministic:
Tests are passing now:
Including my initial way of testing,
I apologize for jumping in here guns blazing - not following this communities practices.
We were talking past each other... and to make amends, I went the extra mile - hope that it is accepted as a fix for this issue.
This is all a learning curve for me.
Thanks everyone 👍