Debug an agent
Enable debug logging on the Comm, Remote, and Health agents, reproduce a problem, collect the log files, and turn debugging off again.
Debug an agent
This guide turns on debug logging for the NetLock RMM agent services on a device, walks through reproducing a problem while logs are being written, and shows where to collect the log files from. By default the agents write no log files at all — not even errors — so an empty or missing Logs folder on a device is normal, not a fault. Debug logging is the on-device counterpart to the server-side Logging page described in A.9.
Each of the three agent services — Comm, Remote, and Health — checks once at process startup whether a file named debug.txt exists in its data directory. The file's content is ignored; an empty file is enough. Because the check runs only at startup, creating or deleting debug.txt takes effect only after the service restarts.
Before you start
- You have administrator or root access on the target device. The agent data directories are protected on every supported OS, so both creating
debug.txtand restarting the services require elevation. - You know which agent you need to debug.
Comm Agenthandles the server connection, policies, jobs, and sensors;Remote Agenthandles remote control sessions;Health Agentsupervises the other two. When in doubt, enable debugging on all three. - Plan to turn debugging off again. Debug logs grow without rotation or a size limit — do not leave
debug.txtin place on a production device after you have collected what you need.
The debug.txt file goes into the agent's data directory. The directory names contain spaces on every OS, so always quote the paths in a shell:
- Windows —
C:\ProgramData\0x101 Cyber Security\NetLock RMM\<Agent>\debug.txt - Linux —
/var/0x101 Cyber Security/NetLock RMM/<Agent>/debug.txt - macOS —
/Library/Application Support/0x101 Cyber Security/NetLock RMM/<Agent>/debug.txt
where <Agent> is Comm Agent, Remote Agent, or Health Agent.
Note: The Health agent checks the other services every 60 seconds and automatically starts a stopped Comm or Remote service. Always use a single
restartcommand rather than stopping a service, waiting, and starting it again — otherwise the watchdog may race you.
Steps
- Create an empty
debug.txtin the data directory of each agent you want to debug.
Windows (PowerShell, elevated):
New-Item -ItemType File -Path "C:\ProgramData\0x101 Cyber Security\NetLock RMM\Comm Agent\debug.txt"
New-Item -ItemType File -Path "C:\ProgramData\0x101 Cyber Security\NetLock RMM\Remote Agent\debug.txt"
New-Item -ItemType File -Path "C:\ProgramData\0x101 Cyber Security\NetLock RMM\Health Agent\debug.txt"Linux (Bash, with sudo):
sudo touch "/var/0x101 Cyber Security/NetLock RMM/Comm Agent/debug.txt"
sudo touch "/var/0x101 Cyber Security/NetLock RMM/Remote Agent/debug.txt"
sudo touch "/var/0x101 Cyber Security/NetLock RMM/Health Agent/debug.txt"macOS (Terminal, with sudo):
sudo touch "/Library/Application Support/0x101 Cyber Security/NetLock RMM/Comm Agent/debug.txt"
sudo touch "/Library/Application Support/0x101 Cyber Security/NetLock RMM/Remote Agent/debug.txt"
sudo touch "/Library/Application Support/0x101 Cyber Security/NetLock RMM/Health Agent/debug.txt"- Restart the agent services so they pick up the file. When you enabled debugging on more than one agent, simply restart all three.
Windows (PowerShell, elevated):
Restart-Service NetLock_RMM_Agent_Comm
Restart-Service NetLock_RMM_Agent_Remote
Restart-Service NetLock_RMM_Agent_HealthLinux (Bash, with sudo):
sudo systemctl restart netlock-rmm-agent-comm
sudo systemctl restart netlock-rmm-agent-remote
sudo systemctl restart netlock-rmm-agent-healthmacOS (Terminal, with sudo):
sudo launchctl kickstart -k system/com.netlock.rmm.agent.comm
sudo launchctl kickstart -k system/com.netlock.rmm.agent.remote
sudo launchctl kickstart -k system/com.netlock.rmm.agent.health-
Reproduce the problem. Trigger the failing action again — run the job, start the remote session, wait for the sync cycle — so the agents write log lines while the problem happens.
-
Collect the logs. Each agent writes JSON-lines
.txtfiles into aLogssubfolder next to itsdebug.txt(for exampleC:\ProgramData\0x101 Cyber Security\NetLock RMM\Comm Agent\Logs\). The key files areDebug.txtandError.txt, plus topic files such asJobs.txt,Sensors.txt, andPowerShell.txton the Comm agent orRemote_Control.txton the Remote agent. Copy or zip the entireLogsfolder per agent rather than picking individual files.
Tip: Independent of debug mode, the services' standard output is available too. On Linux, use journald:
journalctl -u netlock-rmm-agent-comm(likewise for theremoteandhealthunits). On macOS, the LaunchDaemons log to/var/log/netlock_rmm_agent.comm.logand/var/log/netlock_rmm_agent.comm_error.log(likewise.remote/.health).
- Disable debugging again. Delete
debug.txtfrom each data directory and restart the services with the same commands as in step 2. Debug logs grow unbounded, so do not skip this on a production device. You can delete the collectedLogsfolders afterwards to reclaim disk space.
Verify it worked
- After step 2, the
Logssubfolder appears in each agent's data directory andDebug.txtinside it grows as the agent works — the Comm agent writes lines on every sync cycle, so within a minute or two the file should have content. - After step 5, the services run without writing new lines — the timestamps on the files in
Logsstop advancing.
Troubleshooting
- No log output appears even though
debug.txtexists. The services were not restarted after the file was created — the check runs only at process startup. Restart all three services as in step 2. On Windows, also check the file name: with hidden file extensions enabled, Explorer'sNew → Text Documentsilently createsdebug.txt.txt, which the agent ignores. Create the file from PowerShell as shown above to be safe. - The agent is offline or cannot reach the server — is debugging pointless? No. The logs are written locally on the device, independent of the server connection, so connection problems are exactly what debug logging is for. Collect the
Logsfolders directly from the device (step 4) instead of expecting anything to show up in the Console. - The Remote agent's
Error.txtshowsINADEQUATE_SECURITYinService.Setup_SignalR, but the device is online. The device runs Windows 8.1 / Server 2012 R2 or older behind a reverse proxy that enforces the HTTP/2 cipher-suite rules; agents from version 3.2.0.4 on are not affected. See X.3.4 — Remote control for the proxy-side workaround for older agents. - The device is behind an HTTP proxy — which proxy did the agent actually pick? With debug logging on, the Comm, Remote and Health agents write the decision to
Debug.txtunderHelper.Proxy_Resolver.Create_Proxyon every start: the mode (auto,manual,none), the proxy address, the authentication method and, if one is used, the user name. The password is never written. No such line means no proxy applies and the agent connects directly, which inautomode is also what you see on a device that reaches the backend without one. The reachability check itself logs underHelper.Connectivity_Probe, including a proxy that answered407. The settings the agent reads come fromproxy.jsonnext toserver_config.json; see Devices behind an HTTP proxy. - A device turns up under
Unauthorized Devicesalthough nobody deauthorized it. The on-device logs cannot show the reason, because that decision is made on the server. Read the device's authentication log in the Console first — see the next section.
When a device becomes unauthorized: read the Authentication tab first
A device that suddenly waits under Devices → Unauthorized Devices although nobody deauthorized it is the one agent problem the on-device logs cannot explain, because the decision is made on the server. From version 3.2.0.4 on, the server writes every agent check-in that it did not accept as a plain success to a per-device authentication log, and the Console shows it in two places:
Devices→ select the device → tab Authentication, for a device that is (again) authorized.Devices → Unauthorized Devices→ row action Authentication log, for a device that just lost its authorization.
Both require the permission "Authentication log" in the device information tabs group of the user settings; accounts that hold the "General" permission received it with the upgrade.
Each row names the endpoint the request hit, the remote address, the agent version, the hardware ID the agent sent next to the one that was stored for the device, and a reason. Repeats of the same state within ten minutes are folded into one row whose counter grows, so a device that polls every 30 seconds while it waits for approval produces one row per ten minutes rather than twenty. The moment authentication succeeds again is recorded as "Authentication succeeded again". Successful check-ins of an authorized device are not listed, so an empty tab means the device has authenticated without trouble.
| Reason | What happened | What to do |
|---|---|---|
| Hardware ID changed: device deauthorized | The access key matched, but the hardware ID the agent sent differed from the stored one. The server stored the new ID and took the authorization away. The details say authorized_before=1. | Compare the two IDs in the row. A Windows agent derives its ID from the SMBIOS system UUID and the mainboard, BIOS and processor identifiers and keeps the result in hardware_id.json (see How the hardware ID is computed and stored), so a new ID means a mainboard replacement, a VM copied or moved with a new SMBIOS UUID, or an image restored on other hardware. Two devices sharing one access key (a cloned image) show alternating IDs from two remote addresses. Re-authorize the device. With the stored file the ID is not recomputed at boot, so a row that comes back after a reboot means the SMBIOS UUID changes between boots (check Get-CimInstance Win32_ComputerSystemProduct on the device) or a second machine uses the same access key. |
| Hardware ID changed again while waiting for approval | The same for a device that was already unauthorized (authorized_before=0). | As above. Several such rows in a short time point at an ID that flips between two values. Two IDs in the previous format (48 characters) that share their last 16 characters were computed from the same processor and differ in one of the hashed inputs, typically the first disk; update the agent, which ends the flipping after one re-authorization. |
| Hardware ID migrated to the new format | The access key matched, and one of the values the agent sent for the previous hardware ID format equalled the stored ID. The server replaced the stored ID with the new one in place, left the authorization as it was and remembered the previous value. The stored ID in the row is the previous value, the received ID the new one. | Nothing for an authorized device: the row appears once per device after the agent update. A device that was already unauthorized at that moment is migrated as well and needs one manual re-authorization, after which it stays stable. |
| Reinstall detected: new access key, waiting for approval | The request carried an unknown access key, but a device with the same name and hardware ID exists. The server moved that device to the new key and set it to unauthorized. The details name the prefix of the previous key. | Expected after a reinstall with a fresh installer. Approve the device. |
| New device created, waiting for approval | Nothing matched, so a new device row was created. Details tenant_id=0 mean the tenant or location GUID of the installer did not resolve; the device is then in no tenant view. | Approve the device. With tenant_id=0, check the installer package. |
| Auto-authorized by its agent package / New device auto-authorized by its agent package | The agent package has an auto-authorization window that was still open. | Nothing. |
| Auto-authorization failed | The window was open, but the authorization could not be written. | Check the server error log; approve the device manually. |
| Not authorized, waiting for approval | The device polls while it waits for approval. | Approve the device. |
| Identity incomplete: hardware ID or device name missing / Identity rejected | The request lacked a hardware ID or a device name, or the stored authorization state was unreadable. | Usually a hand-made or truncated request. A file browser download with an incomplete identity ends here as well, and so does a newly installed Windows agent that could not compute its hardware ID yet because WMI was unavailable at start; it retries on its own and registers once the ID is available. |
| Server error while checking the identity | The check failed with an exception; the details carry the message. The agent treats this answer as a no-op and retries. | Check the server error log and the database connection. |
| Hub connection rejected: … | The Remote agent's connection to the command hub was refused: unknown agent package, device not authorized, hardware ID mismatch, unknown access key or server error. The device row is not changed by the hub. | A hardware ID mismatch here while the HTTP check-ins pass means the Remote agent carries an older identity than the Comm agent; restart the Remote agent service. |
| Deauthorized by the license limit | The number of authorized devices exceeded the license, and the newest devices were deauthorized. The details name the limit and the count at that moment. | Raise the license or reduce the number of authorized devices, then re-authorize. |
The log is written by the server, so agents need no update for it. Rows are kept for 90 days by default (Settings → Retention & cleanup). The server records nothing while the table does not exist yet and says so once in its log, which is why the web console is deployed before the server.
How the hardware ID is computed and stored
Next to the access key, every device identity carries a hardware ID. The server compares it with the stored one on every check-in and treats a difference as a reason to deauthorize (see the table above); it is also the value behind {{device.hwid}} in scripts. The access key remains the identifier to use when you refer to a device from outside.
Windows. From version 3.3.0.1 on, the Comm agent computes the ID from the SMBIOS system UUID (Win32_ComputerSystemProduct.UUID), the mainboard serial (Win32_BaseBoard.SerialNumber), the BIOS serial (Win32_BIOS.SerialNumber) and the processor IDs of all processors (Win32_Processor.ProcessorId, sorted). Placeholders that firmware ships instead of a serial — To be filled by O.E.M., Default string, System Serial Number, an empty value and similar — count as absent. When at least one of the UUID and the two serials is present, the ID is of tier hardware; a whitebox that has only placeholders gets tier os_bound, computed from the processor IDs and the Windows MachineGuid, which is unique per Windows installation and renewed by sysprep /generalize. Both tiers are a SHA-256 hash written as 64 hexadecimal characters; the previous format had 48 characters on x64 and 32 on arm64, so the two are easy to tell apart in the authentication log. Disks are no input any more, so a USB stick at boot, a docking station or a changed boot order no longer affect the ID.
The value is computed once and stored in hardware_id.json in the Comm agent data directory (C:\ProgramData\0x101 Cyber Security\NetLock RMM\Comm Agent\), protected in the same way as server_config.json next to it. On every later start the agent reads the file instead of querying WMI, so a WMI query that is slow or fails at boot cannot change the ID. The file also records the SMBIOS UUID the ID was computed with: when the UUID the machine reports differs from the recorded one — a VM copied with a new UUID, an image moved to other hardware, a replaced mainboard — the agent computes the ID afresh and overwrites the file, which is what keeps clones apart. A VM restored from a backup in place keeps its UUID and with it its identity.
- Deleting the file makes the agent compute the value again on its next start. On unchanged hardware the result is the same ID and the server sees no change, so this is safe when you suspect a corrupted file.
- A full uninstall removes the file together with the access key; an agent update or a repair with
fixkeeps it. After a reinstall with a fresh installer the agent arrives at the same ID, so the server matches the existing device row by name and hardware ID as described in the table above. - Golden images must not contain
server_config.jsonorhardware_id.json. Clones that carry both share one access key; those whose hypervisor kept the UUID also share the ID and merge into one device row, those with a new UUID compute their own ID and show up as alternating IDs from several addresses. Uninstall the agent before you seal the image and install it on each clone after provisioning. - No ID yet. When WMI is unavailable at start and no file exists, the agent sends its identity without a hardware ID and retries in the background. A device that is already authorized stays authorized; a new device is created only once the ID could be computed.
Migration from the previous format. An updated agent sends the new ID together with the values the previous format could have produced on the machine. The server matches the new ID first; when instead one of the previous values equals the stored ID, it rewrites the stored ID in place, leaves the authorization untouched, remembers the previous value with the device, and writes the row "Hardware ID migrated to the new format", which shows the old and the new value side by side. A device that was already unauthorized because of a flipping ID is migrated the same way and needs one manual re-authorization, after which it stays stable. A stored value that none of the sent candidates reproduces — one computed with a disk that has since been removed, for example — takes the "Hardware ID changed" path once; re-authorize the device and it is stable from then on. Scripts that read {{device.hwid}} see the value change once at that moment.
Upgrade in the usual order — web console, then server, then agents. The web console adds the column in which the migration records the previous value, and an older agent against the new server behaves as before; a device is migrated the first time its updated agent checks in.
Linux, macOS and Android. Unchanged: the agents on these platforms keep the identity they had, send no migration data, and produce no authentication log rows because of this change.
Related
- Guide H.1 — Deploy your first agent — install the agent and its three services.
- Uninstall an agent — remove the agent, including its data directories and logs.
- X.3 — Troubleshooting — symptom-cause-fix entries for the most common agent problems.
- A.9 — Logging & protocols — the server-side
Loggingpage, the counterpart to on-device debug logs.