Skip to content

Bug: Multiple scanner plugins overwirte each other's device presence status (devPresentLastScan) #1766

Description

@farmer1232

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.

  • Firefox
  • Chrome
  • Edge
  • Safari (unsupported) - PRs welcome
  • N/A - This is an issue with the backend

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:

  1. :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
  2. :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

  1. Enable at least two scanner plugins that map to CurrentScan (e.g. ARPSCAN + PIHOLEAPI, or ARPSCAN + MTSCAN).
  2. Set them on overlapping but offset schedules (e.g. ARPSCAN at */10, PIHOLEAPI at 5-59/10).
  3. 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

  • I have read and followed the steps in the wiki link above and provided the required debug logs and the log section covers the time when the issue occurs.

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Setup 📥These are probably setup or user environment related issues.Waiting for reply⏳Waiting for the original poster to respond, or discussion in progress.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions