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
In push mode (node β hub, with SYNC_hub_url and SYNC_devices=True set on the node), the node never sends device data β silently. The log shows "Mode 1: PUSH (NODE)" and then nothing: no send attempt, no error, no hint. The hub receives nothing.
Root cause: front/plugins/sync/sync.py builds the source path as f"{INSTALL_PATH}/api/table_devices.json" (β /app/api/table_devices.json), but in the Docker image the API JSON files are written to NETALERTX_API=/tmp/api and /app/api does not exist. The read is guarded by if os.path.exists(file_path): with no else branch, so the push is skipped without a trace. Observed on v26.2.6 and code-verified still present on current main (sync.py line ~109). The hub-side GET handler in server/api_server/sync_endpoint.py already does this correctly via os.environ.get('NETALERTX_API', '/tmp/api').
Expected Behavior
Device data is pushed to the hub after each scan. If the source file is missing, a log line should say so instead of failing silently.
Suggested fix (sync.py):
api_path = os.environ.get('NETALERTX_API', '/tmp/api')
file_path = f"{api_path}/table_devices.json"
plus an else-branch logging that the file was not found.
Steps To Reproduce
- Two Docker instances of NetAlertX (node: RPi4/arm64, hub: arm64), matching API_TOKEN and SYNC_encryption_key
- On the node set: SYNC_hub_url='http://:20212', SYNC_devices=True, SYNC_RUN='always_after_scan'
- Verify inside the node container: /tmp/api/table_devices.json exists, /app/api does not (os.path.exists returns False)
- Run the plugin: docker exec netalertx python3 /app/front/plugins/sync/sync.py
- Observe: "Mode 1: PUSH (NODE)" is logged, then nothing β no request reaches the hub
- Workaround proof: docker exec netalertx ln -s /tmp/api /app/api β the very next run logs "sent successfully" and the hub receives the devices
Relevant app.conf settings
SYNC_RUN='always_after_scan'
SYNC_devices=True
SYNC_plugins=[]
SYNC_node_name='NAX-abcdefab'
SYNC_encryption_key='<redacted>'
API_TOKEN='<redacted>'
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth0']
docker-compose.yml
# equivalent docker run (node, Raspberry Pi 4 / Debian 12 arm64):
# docker run -d --name netalertx --network host --restart unless-stopped \
# -e TZ=America/Los_Angeles -e PORT=20211 \
# -v <PATH>/netalertx/data:/data \
# ghcr.io/jokob-sk/netalertx:latest # v26.2.6
Debug or Trace enabled
Relevant app.log section
Captured with LOG_LEVEL='debug'. Filesystem state verified immediately before the run:
/app/api/table_devices.json exists: False (while /tmp/api/table_devices.json exists: True)
00:13:57 [SYNC] In script
00:13:57 [SYNC] Mode 1: PUSH (NODE) - This is a NODE as SYNC_hub_url, SYNC_devices or SYNC_plugins are set
00:13:57 [SYNC] plugins_to_sync []
<no further SYNC output β script exits, nothing is sent, no error at any log level>
For contrast, the same run after ln -s /tmp/api /app/api:
00:14:09 [SYNC] Tried endpoint: http://:20212/sync, status: 200
00:14:09 [SYNC] Data for "/app/api/table_devices.json" sent successfully via http://:20212/sync
Note: the plugin messages in this code path are emitted at verbose level; debug adds no extra
output here β the defining symptom is the absence of any send/error after "Mode 1".
Docker Logs
--> expected user id match.sh
--> host mode network.sh
--> excessive capabilities.sh
--> appliance integrity.sh
--> ports available.sh
Starting supercronic --quiet "/services/config/cron/crontab" >>"/tmp/log/cron.log" 2>&1 &
Starting /usr/sbin/php-fpm83 -y "/services/config/php/php-fpm.conf" -F (tee stderr to app.php_errors.log)
Starting python3 -m server > /tmp/log/stdout.log 2> >(tee /tmp/log/stderr.log >&2)
Starting /usr/sbin/nginx -p "/tmp/run/" -c "/tmp/nginx/active-config/nginx.conf" -g "error_log stderr; error_log /tmp/log/nginx-error.log; daemon off;" &
Successfully updated IEEE OUI database (114848 entries)
(Container startup is clean β the failure itself produces no docker-log output at all;
the silent skip is only visible in app.log, provided above.)
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
In push mode (node β hub, with SYNC_hub_url and SYNC_devices=True set on the node), the node never sends device data β silently. The log shows "Mode 1: PUSH (NODE)" and then nothing: no send attempt, no error, no hint. The hub receives nothing.
Root cause: front/plugins/sync/sync.py builds the source path as f"{INSTALL_PATH}/api/table_devices.json" (β /app/api/table_devices.json), but in the Docker image the API JSON files are written to NETALERTX_API=/tmp/api and /app/api does not exist. The read is guarded by
if os.path.exists(file_path):with no else branch, so the push is skipped without a trace. Observed on v26.2.6 and code-verified still present on current main (sync.py line ~109). The hub-side GET handler in server/api_server/sync_endpoint.py already does this correctly via os.environ.get('NETALERTX_API', '/tmp/api').Expected Behavior
Device data is pushed to the hub after each scan. If the source file is missing, a log line should say so instead of failing silently.
Suggested fix (sync.py):
api_path = os.environ.get('NETALERTX_API', '/tmp/api')
file_path = f"{api_path}/table_devices.json"
plus an else-branch logging that the file was not found.
Steps To Reproduce
Relevant
app.confsettingsdocker-compose.yml
Debug or Trace enabled
Relevant
app.logsectionCaptured with LOG_LEVEL='debug'. Filesystem state verified immediately before the run:
/app/api/table_devices.json exists: False (while /tmp/api/table_devices.json exists: True)
00:13:57 [SYNC] In script
00:13:57 [SYNC] Mode 1: PUSH (NODE) - This is a NODE as SYNC_hub_url, SYNC_devices or SYNC_plugins are set
00:13:57 [SYNC] plugins_to_sync []
<no further SYNC output β script exits, nothing is sent, no error at any log level>
For contrast, the same run after
ln -s /tmp/api /app/api:00:14:09 [SYNC] Tried endpoint: http://:20212/sync, status: 200
00:14:09 [SYNC] Data for "/app/api/table_devices.json" sent successfully via http://:20212/sync
Note: the plugin messages in this code path are emitted at verbose level; debug adds no extra
output here β the defining symptom is the absence of any send/error after "Mode 1".
Docker Logs
--> expected user id match.sh
--> host mode network.sh
--> excessive capabilities.sh
--> appliance integrity.sh
--> ports available.sh
Starting supercronic --quiet "/services/config/cron/crontab" >>"/tmp/log/cron.log" 2>&1 &
Starting /usr/sbin/php-fpm83 -y "/services/config/php/php-fpm.conf" -F (tee stderr to app.php_errors.log)
Starting python3 -m server > /tmp/log/stdout.log 2> >(tee /tmp/log/stderr.log >&2)
Starting /usr/sbin/nginx -p "/tmp/run/" -c "/tmp/nginx/active-config/nginx.conf" -g "error_log stderr; error_log /tmp/log/nginx-error.log; daemon off;" &
Successfully updated IEEE OUI database (114848 entries)
(Container startup is clean β the failure itself produces no docker-log output at all;
the silent skip is only visible in app.log, provided above.)