Start here
The installer stopped and printed nothing useful
The script runs with set -e: the first command that fails ends the run
immediately, and the failing command's own error may have scrolled past. Run it again
with a trace, and keep the last lines:
curl -fsSL https://raw.githubusercontent.com/jasoncheng7115/jt-wazuh-mgr/main/install.sh -o /tmp/jt-install.sh
sudo bash -x /tmp/jt-install.sh 2>&1 | tail -40
The last + line before the error is the exact command that failed. Match it
against the sections below.
What the installer touches, so you know what to check
/opt/jt-wazuh-mgr/— program files, rule packs, and yourconfig.yaml/etc/systemd/system/jt-wazuh-mgr.service— the service unit, rewritten on every run- Python packages from
requirements.txt, installed withpip
config.yaml is downloaded
only when it does not already exist. Upgrading never overwrites it.Where does it have to be installed?
On the Wazuh Manager itself — and on the master node if you run a cluster.
The tool reads the ruleset and the manager's own files from /var/ossec, so it
cannot manage a manager from somewhere else.
Check you are on a manager, not an agent:
/var/ossec/bin/wazuh-control info
ls /var/ossec/etc/rules/ # managers have this; agents do not
Downloads fail
curl: (6) Could not resolve host / (7) Failed to connect
curl: (6) Could not resolve host: raw.githubusercontent.comThe manager has no route to GitHub. That is normal — plenty of Wazuh managers sit on an isolated network on purpose. Two ways forward:
- If a proxy exists, set it before running the installer:
export https_proxy=http://proxy.example.com:3128 export http_proxy=$https_proxy curl -fsSL https://raw.githubusercontent.com/jasoncheng7115/jt-wazuh-mgr/main/install.sh | sudo -E bashsudo -Ematters — without it sudo drops the proxy variables. - If there is no route at all, use the offline install below.
curl: (60) SSL certificate problem
curl: (60) SSL certificate problem: unable to get local issuer certificateUsually one of two things: the CA bundle is out of date, or a corporate appliance is intercepting TLS and presenting its own certificate.
# refresh the CA bundle
sudo apt update && sudo apt install --reinstall ca-certificates # Debian / Ubuntu
sudo dnf reinstall ca-certificates # RHEL / Rocky
If an appliance is inspecting traffic, add its CA to the system store rather than
disabling verification. Do not use curl -k for an installer — you would be
downloading code you cannot authenticate.
Installed, but the Rule Packs tab is empty
Rule pack files are downloaded on a best-effort basis: if the index or a file cannot be fetched, the installer says so and carries on rather than failing the whole install.
- packs (skipped, index unavailable)Re-run the installer once connectivity is back. Nothing else needs undoing.
Python dependencies
error: externally-managed-environment
error: externally-managed-environment × This environment is externally managedDebian 12, Ubuntu 23.04 and later refuse pip install into the system Python,
to stop pip and the distribution's package manager fighting over the same files. This is
the single most common reason an install or upgrade stops on a current OS.
Pick one, in this order of preference:
- Install the dependencies as distribution packages. Cleanest, and it survives
OS upgrades:
Then re-run the installer — pip will find everything already present.sudo apt install python3-flask python3-requests python3-yaml - Tell pip you accept the risk, if the distribution packages are too old:
The flag is named honestly: pip may replace files the package manager owns.sudo pip install --break-system-packages -r /opt/jt-wazuh-mgr/requirements.txt sudo systemctl restart jt-wazuh-mgr - Use a virtual environment if you want full isolation — see running from a virtual environment.
pip: command not found
install.sh: line 107: pip: command not foundMany systems ship pip3 without a pip alias, and some ship
neither. Install it, then re-run the installer:
sudo apt install python3-pip # Debian / Ubuntu
sudo dnf install python3-pip # RHEL / Rocky / Alma
If your policy forbids pip entirely, install the three dependencies as distribution packages instead — see the previous answer.
pip cannot reach PyPI
WARNING: Retrying ... Connection to pypi.org timed outSame isolation as the download failures above, at a later step. The program files are already in place at this point; only the dependencies are missing. Install them from your distribution's packages, or from wheels you copy in yourself — see offline install.
Running from a virtual environment
If you prefer to keep everything out of the system Python:
sudo python3 -m venv /opt/jt-wazuh-mgr/venv
sudo /opt/jt-wazuh-mgr/venv/bin/pip install -r /opt/jt-wazuh-mgr/requirements.txt
Then point the service at it with a drop-in, which survives future upgrades:
sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
Environment=PATH=/opt/jt-wazuh-mgr/venv/bin:/usr/bin:/bin
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr
The service will not start
Read the actual reason first
Two commands say what went wrong; almost every answer below comes from them:
systemctl status jt-wazuh-mgr --no-pager -l
journalctl -u jt-wazuh-mgr -n 50 --no-pager
ModuleNotFoundError: No module named 'flask'
ModuleNotFoundError: No module named 'flask'The files installed but the dependencies did not — the pip step failed earlier, and with
set -e you may not have noticed. Go back to
Python dependencies, then:
sudo systemctl restart jt-wazuh-mgr
Address already in use / nothing answers on port 5000
OSError: [Errno 98] Address already in useSomething else holds the port. Find it:
sudo ss -tlnp | grep :5000
Either stop that service, or move this one with a drop-in so an upgrade will not undo it:
sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
ExecStart=
ExecStart=/opt/jt-wazuh-mgr/wazuh_agent_mgr.py --web --ssl-auto --port 5443
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr
The empty ExecStart= is required: it clears the original line before the new
one is added.
The service starts but the browser cannot connect
Work outwards from the machine itself. If the first command answers and the second does not, it is the firewall, not the tool:
curl -kIs https://127.0.0.1:5000/ | head -1 # on the manager
sudo firewall-cmd --add-port=5000/tcp --permanent && sudo firewall-cmd --reload # RHEL family
sudo ufw allow 5000/tcp # Ubuntu
Note the URL is https. With --ssl-auto the tool serves the Wazuh
dashboard's own certificate when the dashboard runs on the same host (1.11.3 and later);
otherwise the certificate is self-signed and the browser warns once.
"Connection Lost" right after opening the Wazuh dashboard
Chrome and Edge keep your "proceed anyway" for a self-signed certificate per host, not per port, and drop it the moment they see a valid certificate on that host. When the dashboard runs on the same machine with a certificate your browser trusts, opening it cancels the exception the tool was using: every request then fails in the TLS handshake, the page shows Connection Lost, and the tool's log shows nothing, because nothing arrives. Pressing F5 brings the certificate warning back. Firefox is not affected.
Upgrade to 1.11.3 or later and keep --ssl-auto: the tool then serves the
dashboard's certificate, so there is no exception to lose. With your own certificate,
use one your browsers trust:
./wazuh_agent_mgr.py --web --ssl-cert /path/to/cert.pem --ssl-key /path/to/key.pem
If instead the page says Session expired and returns to the login page, the Wazuh
API revoked the token. Look for DELETE /security/user/authenticate or
PUT /security/user/revoke in /var/ossec/logs/api.log at that
moment, and log in to the tool with an API user of its own rather than the
dashboard's wazuh-wui.
Upgrades
The upgrade finished but the version did not change
Read the version back from the installed path rather than trusting the installer's summary line:
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py
systemctl is-active jt-wazuh-mgr
If the file says the new version but the interface still shows the old one, clear stale bytecode and restart:
sudo rm -rf /opt/jt-wazuh-mgr/lib/__pycache__
sudo systemctl restart jt-wazuh-mgr
Then reload the browser with cache bypassed (Ctrl+Shift+R).
My customised service file was replaced by the upgrade
/etc/systemd/system/jt-wazuh-mgr.service. Any edit you made directly to that
file — a different port, a User=, an Environment= line — is lost
on the next upgrade.Restore it once, then make the change survive by moving it into a drop-in, which the installer never touches:
sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
Environment=PYTHONPATH=/opt/jt-wazuh-mgr/vendor
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr
Check what is in effect afterwards with systemctl cat jt-wazuh-mgr.
Will an upgrade touch my configuration or my installed rule packs?
No. config.yaml is skipped when it already exists. Rule packs you have
installed live in the Wazuh manager's own directories
(/var/ossec/etc/rules, etc/lists, etc/decoders) with
their state in /var/ossec/etc/jt-packs/; upgrading the tool only refreshes the
catalogue it offers you.
When the refreshed catalogue holds a newer version of a pack you installed, the Rule Packs tab offers Update next to it (1.12.0 and later). It shows what will change first, leaves the lists you maintain and any file you edited as they are unless you choose otherwise, and lists the agent-side steps that are new since your version. Reload the ruleset on every node afterwards.
Going back to the previous version
Take a copy before upgrading and you can always return to it:
sudo tar czf /root/jt-wazuh-mgr-backup-$(date +%F).tar.gz -C /opt jt-wazuh-mgr
# to roll back
sudo systemctl stop jt-wazuh-mgr
sudo tar xzf /root/jt-wazuh-mgr-backup-YYYY-MM-DD.tar.gz -C /opt
sudo systemctl start jt-wazuh-mgr
-C. Extracting without it unpacks into the current
directory, and a later version check can read the wrong copy and report success while
nothing changed.Offline and air-gapped installs
How do I install or upgrade when the manager has no internet access?
Build one archive on a machine that has internet access — the release plus the Python wheels for the manager's Python version — copy it over, and run the installer from it:
tar xzf /root/jt-wazuh-mgr-X.Y.Z-offline.tar.gz -C /root
sudo bash /root/jt-wazuh-mgr-X.Y.Z/install.sh --offline
With --offline the installer copies everything from the extracted directory and installs the wheels
from its wheels/ directory into /opt/jt-wazuh-mgr/vendor; it never runs curl,
apt or dnf, and pip is optional. Upgrades work the same way and keep config.yaml.
The full procedure — building the archive, matching the Python version, verifying, upgrading, rolling back and the manual steps for v1.19.0 and earlier — is on its own page: Offline install & upgrade.
Installed, but something is wrong
The login page appears but the credentials are rejected
The username and password are a Wazuh API user, not an operating system account and not your dashboard login. Confirm the API answers first:
curl -k -u <user>:<password> https://127.0.0.1:55000/security/user/authenticate
The password generated at installation time is inside
wazuh-install-files.tar, in whichever directory you ran the Wazuh installer
from. To create a dedicated account for this tool:
sudo /opt/jt-wazuh-mgr/create_api_user.py
The configuration editor has no syntax highlighting
The editor component is loaded from a CDN, so it is unavailable on an isolated network. Editing still works; only the colouring is missing. Nothing needs fixing.
Removing it completely
sudo bash /opt/jt-wazuh-mgr/uninstall.sh
Rule packs you installed into the manager are not removed by this — remove those from the Rule Packs tab first if you want them gone, so that the original files are restored properly.
Still stuck
What to include when you ask
These four make almost any install problem diagnosable at a glance:
cat /etc/os-release | head -2
python3 -V
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py
journalctl -u jt-wazuh-mgr -n 50 --no-pager
Plus the last 40 lines of bash -x output from the first answer on this page.
Open an issue at
github.com/jasoncheng7115/jt-wazuh-mgr/issues.