Install & upgrade
troubleshooting

The installer stops at the first command that fails, so a failure often looks like nothing at all. Find the message you saw below — the answers say what the installer was doing at that moment and what to run instead.

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 your config.yaml
  • /etc/systemd/system/jt-wazuh-mgr.service — the service unit, rewritten on every run
  • Python packages from requirements.txt, installed with pip
Your configuration is safe. 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.com

The 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 bash
    sudo -E matters — 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 certificate

Usually 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 managed

Debian 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:

  1. Install the dependencies as distribution packages. Cleanest, and it survives OS upgrades:
    sudo apt install python3-flask python3-requests python3-yaml
    Then re-run the installer — pip will find everything already present.
  2. Tell pip you accept the risk, if the distribution packages are too old:
    sudo pip install --break-system-packages -r /opt/jt-wazuh-mgr/requirements.txt
    sudo systemctl restart jt-wazuh-mgr
    The flag is named honestly: pip may replace files the package manager owns.
  3. 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 found

Many 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 out

Same 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 use

Something 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, and with --ssl-auto the certificate is self-signed, so the browser will warn once.

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

Known behaviour. Every run copies the shipped unit over /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.

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
Use -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

Installing where the manager has no internet at all

Do the fetching on a machine that has a connection, then carry the result across.

On the connected machine:

git clone --depth 1 https://github.com/jasoncheng7115/jt-wazuh-mgr.git
tar czf jt-wazuh-mgr.tgz -C jt-wazuh-mgr lib packs images \
    wazuh_agent_mgr.py create_api_user.py requirements.txt \
    config.yaml jt-wazuh-mgr.service uninstall.sh
pip download -r jt-wazuh-mgr/requirements.txt -d wheels
tar czf wheels.tgz wheels

On the manager:

sudo mkdir -p /opt/jt-wazuh-mgr
sudo tar xzf jt-wazuh-mgr.tgz -C /opt/jt-wazuh-mgr
tar xzf wheels.tgz
sudo pip install --no-index --find-links=wheels -r /opt/jt-wazuh-mgr/requirements.txt
sudo cp /opt/jt-wazuh-mgr/jt-wazuh-mgr.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now jt-wazuh-mgr
Build the wheels on a matching Python. Compiled packages are built for one interpreter version: wheels made for Python 3.10 fail to import on 3.12. Check python3 -V on both machines first.

Upgrading an offline install

Do not run install.sh there — it will try to reach GitHub and PyPI, and it will overwrite a service unit you may have customised for this environment. Replace the program files only:

sudo systemctl stop jt-wazuh-mgr
sudo tar xzf jt-wazuh-mgr.tgz -C /opt/jt-wazuh-mgr
sudo rm -rf /opt/jt-wazuh-mgr/lib/__pycache__
sudo systemctl start jt-wazuh-mgr
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py

Dependencies rarely change between releases; if requirements.txt did change, carry across a fresh set of wheels as well.

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.

Before you paste. Logs from a Wazuh manager carry host names and addresses from your estate. Replace anything you would not put on a public page.
No answer matches that. Try a word from the error message itself.