What installation are you running?
Production (netalertx) 📦
Is there an existing issue for this?
The issue occurs in the following browsers. Select at least 2.
Current Behavior
Bug Description
When multiple scanner plugins are enabled (e.g. ARPSCAN + PIHOLEAPI, or ARPSCAN + MTSCAN), each plugin's scan cycle resets devPresentLastScan to 0 for all devices not found in that specific scan, regardless of which plugin originally discovered them. This causes devices to constantly flip between online and offline (flapping), even though they are correctly detected by their respective scanner.
Root Cause
In server/scan/device_handling.py, function update_presence_from_CurrentScan() (around line 195), the second SQL query unconditionally resets all devices not in CurrentScan:
# Mark not present if not in CurrentScan
sql.execute("""
UPDATE Devices
SET devPresentLastScan = 0
WHERE NOT EXISTS (
SELECT 1 FROM CurrentScan
WHERE devMac = scanMac
)
""")
Since CurrentScan is cleared (DELETE FROM CurrentScan) after each plugin's process_scan() cycle, the next plugin to run will reset all devices from the previous plugin to devPresentLastScan = 0.
Example scenario:
:00 — ARPSCAN finds 12 devices (real MACs) → inserts into CurrentScan → process_scan() sets devPresentLastScan=1 for those 12, resets ALL others to 0 → DELETE FROM CurrentScan
:05 — PIHOLEAPI finds its devices (synthetic ip-X.X.X.X MACs) → inserts into CurrentScan → process_scan() → no ARPSCAN device matches (different MAC format) → all ARPSCAN devices get devPresentLastScan=0
Proposed Fix
Add a WHERE clause to scope the reset to only devices belonging to the same source plugin(s) present in the current scan batch:
# Mark not present if not in CurrentScan
sql.execute("""
UPDATE Devices
SET devPresentLastScan = 0
WHERE NOT EXISTS (
SELECT 1 FROM CurrentScan
WHERE devMac = scanMac
)
AND devSourcePlugin IN (
SELECT DISTINCT scanSourcePlugin FROM CurrentScan
)
""")
This ensures that ARPSCAN only resets ARPSCAN-sourced devices, PIHOLEAPI only resets PIHOLEAPI-sourced devices, etc. — eliminating cross-plugin interference.
Steps to Reproduce
- Enable at least two scanner plugins that map to
CurrentScan (e.g. ARPSCAN + PIHOLEAPI, or ARPSCAN + MTSCAN).
- Set them on overlapping but offset schedules (e.g. ARPSCAN at
*/10, PIHOLEAPI at 5-59/10).
- Observe
devPresentLastScan in the Devices table — devices from one plugin will flip to 0 after the other plugin's scan cycle.
Environment
- NetAlertX version: v26.8.5
- Docker deployment,
network_mode: host
- Multiple VLAN subnets scanned via ARPSCAN
- PIHOLEAPI and MTSCAN (Mikrotik) also enabled
Impact
- Device status constantly flapping between Online/Offline in the UI
- False disconnect/reconnect notifications
- Unreliable presence detection when using multiple scanners (which is a common and recommended setup)
Expected Behavior
Devices found by ARPSCAN should stay online regardless of other plugins running.
Steps To Reproduce
Enable ARPSCAN + PIHOLEAPI on offset schedules, Observe devPresentLastScan flapping.
Relevant app.conf settings
docker-compose.yml
Debug or Trace enabled
Relevant app.log section
N/A - root cause identified in source code, patch provided in description
Docker Logs
N/A - see description for full analysis
What installation are you running?
Production (netalertx) 📦
Is there an existing issue for this?
The issue occurs in the following browsers. Select at least 2.
Current Behavior
Bug Description
When multiple scanner plugins are enabled (e.g. ARPSCAN + PIHOLEAPI, or ARPSCAN + MTSCAN), each plugin's scan cycle resets
devPresentLastScanto0for all devices not found in that specific scan, regardless of which plugin originally discovered them. This causes devices to constantly flip between online and offline (flapping), even though they are correctly detected by their respective scanner.Root Cause
In
server/scan/device_handling.py, functionupdate_presence_from_CurrentScan()(around line 195), the second SQL query unconditionally resets all devices not inCurrentScan:Since
CurrentScanis cleared (DELETE FROM CurrentScan) after each plugin'sprocess_scan()cycle, the next plugin to run will reset all devices from the previous plugin todevPresentLastScan = 0.Example scenario:
:00— ARPSCAN finds 12 devices (real MACs) → inserts intoCurrentScan→process_scan()setsdevPresentLastScan=1for those 12, resets ALL others to 0 →DELETE FROM CurrentScan:05— PIHOLEAPI finds its devices (syntheticip-X.X.X.XMACs) → inserts intoCurrentScan→process_scan()→ no ARPSCAN device matches (different MAC format) → all ARPSCAN devices getdevPresentLastScan=0Proposed Fix
Add a
WHEREclause to scope the reset to only devices belonging to the same source plugin(s) present in the current scan batch:This ensures that ARPSCAN only resets ARPSCAN-sourced devices, PIHOLEAPI only resets PIHOLEAPI-sourced devices, etc. — eliminating cross-plugin interference.
Steps to Reproduce
CurrentScan(e.g. ARPSCAN + PIHOLEAPI, or ARPSCAN + MTSCAN).*/10, PIHOLEAPI at5-59/10).devPresentLastScanin theDevicestable — devices from one plugin will flip to0after the other plugin's scan cycle.Environment
network_mode: hostImpact
Expected Behavior
Devices found by ARPSCAN should stay online regardless of other plugins running.
Steps To Reproduce
Enable ARPSCAN + PIHOLEAPI on offset schedules, Observe devPresentLastScan flapping.
Relevant
app.confsettingsdocker-compose.yml
Debug or Trace enabled
Relevant
app.logsectionN/A - root cause identified in source code, patch provided in description
Docker Logs
N/A - see description for full analysis