I moved two Zabbix 7.0 LTS servers to 8.0 this week. The schema upgrade I’d braced for was the boring bit: about 9 seconds on MariaDB, 28 on PostgreSQL. What stopped me was the Rocky box answering “Manual intervention is required to complete upgrade!” instead of a login page. Going straight from 7.0 LTS means taking every release since 7.0 at once, because 7.2 moved the frontend files and 8.0 raised the PHP and database minimums.
I ran the upgrade from Zabbix 7.0.32 in October 2026 on an Ubuntu 26.04.1 VM (MariaDB, Apache) and a Rocky Linux 10.2 VM (PostgreSQL, Nginx), plus Rocky 9.7 and Ubuntu 24.04 scratch VMs for the old-stack and second-LTS checks. Zabbix 8.0 is still at release candidate 8.0.0rc2, so the lab packages came from the zabbix/8.0/unstable tree on repo.zabbix.com. On production I’d wait until apt-cache policy zabbix-server-mysql or dnf info zabbix-server-pgsql shows a candidate from the release tree (the repository swap section shows where to look).
Seeing what the upgrade touches
Both lab servers ran everything on one VM: the web server, PHP-FPM, zabbix-server, agent 2 and the database. This is what the upgrade changes on a box like that:

The packages only replace files. The real changes happen in two places afterwards: zabbix-server rewrites the database schema the first time it starts, and your web server has to point at the frontend’s new home in /usr/share/zabbix/ui. On the Rocky box rpm kept my edited Nginx config, which still pointed at the old path, so that is the red route in the diagram.
Checking your server before the 7.0 to 8.0 upgrade
Zabbix 8.0 needs PHP 8.2 or newer for the frontend, and it refuses databases that 7.0 was happy with. Do you need a stop at 7.2 or 7.4 on the way? No. Zabbix supports a direct upgrade to 8.0 from any release since 2.0, but the jump means the 7.2 and 7.4 upgrade notes apply to you as well as the 8.0 ones. The official upgrade page lists them per starting version, and these are the floors that changed.
| Component | Zabbix 7.0 LTS accepts | Zabbix 8.0 requires |
|---|---|---|
| PHP (frontend) | 8.0.0 to 8.5.x | 8.2.0 to 8.5.x |
| MariaDB | 10.5.00 to 12.3.x | 10.11.00 to 12.3.x |
| MySQL / Percona | 8.0.30 to 9.7.x | 8.4.0 to 9.7.x |
| PostgreSQL | 13.0 to 18.x | 15.0 to 18.x |
| TimescaleDB minimum | 2.13.0 | 2.20.0 |
| Oracle DB | Supported (deprecated) | Dropped since 7.2 |
Neither apt nor dnf enforces any of this. The 8.0 zabbix-web RPM only asks for php-fpm >= 7.2, so dnf put the whole 8.0 stack on a Rocky 9 box running PHP 8.0 without a word. The failure only showed up when I started the server and opened the browser. These are the versions the four boxes I tested shipped with by default.
| Lab box | PHP | Database | Ready for 8.0? |
|---|---|---|---|
| Ubuntu 26.04.1 LTS | 8.5.4 | MariaDB 11.8.6 | Yes |
| Ubuntu 24.04.4 LTS | 8.3.6 | MariaDB 10.11.14 | Yes |
| Rocky Linux 10.2 | 8.4.27 | PostgreSQL 16.15 | Yes |
| Rocky Linux 9.7 (default streams) | 8.0.30 | MariaDB 10.5.29 | No, both too old |
So the two current LTS pairs are fine as shipped, and the box you need to worry about is the older one that was installed years ago and never had its PHP or database touched. Check yours before anything else. On Ubuntu the PHP CLI comes in with the frontend, so php -v reports the version PHP-FPM runs.
php -v | head -1
mariadb --version
On the Ubuntu 26.04 box both are comfortably inside the 8.0 ranges:
PHP 8.5.4 (cli) (built: Oct 19 2026 14:35:18) (NTS)
mariadb from 11.8.6-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper
Rocky Linux doesn’t install the PHP CLI with the Zabbix frontend, only PHP-FPM, so ask FPM directly. Swap psql --version for mariadb --version if your Zabbix database is MariaDB.
php-fpm -v | head -1
psql --version
Rocky 10.2 already carries PHP 8.4 in its AppStream, which surprised me, since I’d half expected 8.3. PostgreSQL 16 is well inside the new range:
PHP 8.4.27 (fpm-fcgi) (built: Oct 19 2026 14:38:59) (NTS gcc x86_64)
psql (PostgreSQL) 16.15
If you’re on MariaDB or MySQL, there’s one more thing the 8.0 upgrade notes ask for: a database created as utf8mb3 should be converted to utf8mb4 with utf8mb4_bin collation before the upgrade. Check what yours uses.
sudo mariadb -N -e "SELECT default_character_set_name, default_collation_name FROM information_schema.SCHEMATA WHERE schema_name='zabbix';"
Mine was created the way the 7.0 install guide says, so it came back clean:
utf8mb4 utf8mb4_bin
Anything else there, utf8mb3 in particular, means running Zabbix’s charset repair procedure first. I didn’t have a utf8mb3 database to try it on, so I can’t tell you how long it takes on a big one.
Backing up the database and the configs
The server rewrites the schema the first time 8.0 starts, and nothing in the packages can put it back, so the dump you take now is the only way home. Stop the server first so nothing writes while you dump. If this box also runs Zabbix agent instead of agent 2, stop zabbix-agent too.
sudo systemctl stop zabbix-server zabbix-agent2
sudo mkdir -p /opt/zabbix-backup
With MariaDB or MySQL, dump with --single-transaction and keep the triggers and routines, which the schema uses:
sudo mariadb-dump --single-transaction --routines --triggers zabbix | gzip | sudo tee /opt/zabbix-backup/zabbix-70.sql.gz > /dev/null
With PostgreSQL, the custom format is the one pg_restore reads back. The directory has to be writable by the postgres user:
sudo chown postgres /opt/zabbix-backup
sudo -u postgres pg_dump -Fc -f /opt/zabbix-backup/zabbix-70.dump zabbix
Both lab dumps took about a second and came out at 4.0 MB and 4.4 MB, which says more about my small test databases than about yours. A production Zabbix with months of history can run to hundreds of gigabytes, so check the free space under /opt before you start the dump, not halfway through it. Copy the configs next to the dump. On Ubuntu with Apache, that’s two lines:
sudo cp /etc/zabbix/zabbix_server.conf /etc/zabbix/zabbix_agent2.conf /etc/zabbix/web/zabbix.conf.php /opt/zabbix-backup/
sudo cp /etc/apache2/conf-enabled/zabbix.conf /opt/zabbix-backup/apache-zabbix.conf
If your Ubuntu frontend runs on Nginx, copy /etc/zabbix/nginx.conf instead of the Apache file.
On Rocky with Nginx, give the two files called zabbix.conf different names, because my first copy put both into one directory and cp refused to overwrite the first with the second:
sudo cp /etc/zabbix/zabbix_server.conf /etc/zabbix/zabbix_agent2.conf /etc/zabbix/web/zabbix.conf.php /opt/zabbix-backup/
sudo cp /etc/nginx/conf.d/zabbix.conf /opt/zabbix-backup/nginx-zabbix.conf
sudo cp /etc/php-fpm.d/zabbix.conf /opt/zabbix-backup/php-fpm-zabbix.conf
On Rocky with Apache, the web server file to copy is /etc/httpd/conf.d/zabbix.conf.
If the box is a VM, take a snapshot as well. It’s a far quicker way back than the package rollback at the end of this page. We have guides for snapshots on Proxmox and LVM snapshots for bare metal.
Fixing Rocky Linux 9’s old PHP and MariaDB
I wanted to see what skipping the checks actually costs, so I put Zabbix 7.0 on a Rocky Linux 9.7 VM with nothing but its default streams (MariaDB 10.5 and PHP 8.0) and pushed the 8.0 packages onto it. Skip this section if your checks above passed. If they didn’t, these are the two errors you’ll meet, and the fix for both.
Unable to start Zabbix server due to unsupported MariaDB database version
The service never comes up, and systemctl only says the unit “did not take the steps required by its unit configuration”. The reason is in /var/log/zabbix/zabbix_server.log:
17738:20261023:130014.734 Unable to start Zabbix server due to unsupported MariaDB database version (10.5.29).
17738:20261023:130014.734 Must be at least (10.11.0).
17738:20261023:130014.734 Use of supported database version is highly recommended.
17738:20261023:130014.734 Override by setting AllowUnsupportedDBVersions=1 in Zabbix server configuration file at your own risk.
17738:20261023:130014.734 ==================================================
17738:20261023:130014.735 [Z3005] query failed: [1146] Table 'zabbix.settings' doesn't exist [select 1 from settings where name='dbversion_status']
17738:20261023:130014.735 Zabbix Server stopped. Zabbix 8.0.0rc2 (revision f3e1632e2ec).
What saved me is that the server stops before it touches the schema, so the database was still at the 7.0 version when I went to fix it. I’d leave AllowUnsupportedDBVersions alone: it gets the daemon running on a database Zabbix hasn’t tested 8.0 against, and you’d find out what that means in production.
Minimum required PHP version is 8.2.0
The frontend fails differently: every page, including the API endpoint, returns one line of text. I asked the API for its version and got this back:
curl -s -X POST -H 'Content-Type: application/json-rpc' -d '{"jsonrpc":"2.0","method":"apiinfo.version","params":{},"id":1}' http://localhost/zabbix/api_jsonrpc.php
Anything that polls the API gets that string back instead of JSON:
Minimum required PHP version is 8.2.0.
Rocky 9’s AppStream fixes both through module streams, so no third-party repo is needed. List what’s on offer first.
dnf module list mariadb php
The 10.11 MariaDB stream and the 8.2 and 8.3 PHP streams all clear the 8.0 floor:
mariadb 10.11 client, galera, server [d] MariaDB Module
mariadb 11.8 client, galera, server [d] MariaDB Module
php 8.1 common [d], devel, minimal PHP scripting language
php 8.2 common [d], devel, minimal PHP scripting language
php 8.3 common [d], devel, minimal PHP scripting language
Switching MariaDB streams is an in-place major upgrade of the database server, so do it after the dump from the previous section, never before. Stop everything that talks to the database, switch, start it again and let mariadb-upgrade update the system tables:
sudo systemctl stop zabbix-server httpd php-fpm mariadb
sudo dnf -y module switch-to mariadb:10.11
sudo systemctl start mariadb
sudo mariadb-upgrade
The switch took under 4 seconds and mariadb-upgrade finished with OK. PHP is a one-liner after that, and PHP-FPM needs a restart to pick it up:
sudo dnf -y module switch-to php:8.2
sudo systemctl restart php-fpm httpd
php-fpm -v | head -1
FPM now reports the 8.2 stream. The frontend dropped the PHP error as soon as FPM came back, and the API returned JSON again:
PHP 8.2.35 (fpm-fcgi) (built: Oct 19 2026 07:29:52)
On that box I’d already installed the 8.0 packages, so starting zabbix-server after the switch kicked off the schema upgrade straight away, and it finished in 17 seconds with SELinux still enforcing and no AVC denials. On your box, do the switch now and carry on with the Rocky repository steps below, using the EL9 release package shown there. I picked 8.2 because it was the smallest jump from 8.0; I didn’t test the 8.3 stream with Zabbix 8.0 on Rocky 9.
Upgrading Zabbix on Ubuntu 26.04 and 24.04
The Ubuntu path is a repository swap and an apt run, and the one trap is the old repository file. Download the 7.0 release package first and keep it in your home directory. You won’t install it now, but the rollback needs it, and it’s easier to grab while you still know which one you had:
cd ~
. /etc/os-release
wget "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
Now remove the 7.0 source. On both 26.04 and 24.04 the 7.0 release package writes /etc/apt/sources.list.d/zabbix.sources, not the zabbix.list that Zabbix’s upgrade page tells you to delete. The 8.0 release package no longer ships that file, so dpkg marks it obsolete and leaves it on disk. On my first run apt kept fetching the 7.0 repository next to the 8.0 ones, and nothing complained until the rollback test. The rm covers both names:
sudo rm -f /etc/apt/sources.list.d/zabbix.sources /etc/apt/sources.list.d/zabbix.list
Install the 8.0 release package for your Ubuntu version and refresh the indexes. VERSION_ID from the line above picks the 26.04 or 24.04 file:
wget "https://repo.zabbix.com/zabbix/8.0/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_8.0+ubuntu${VERSION_ID}_all.deb"
sudo dpkg -i "zabbix-release_latest_8.0+ubuntu${VERSION_ID}_all.deb"
sudo apt update
apt-cache policy zabbix-server-mysql | head -6
Look at where the candidate comes from before you go further. The 8.0 release package leaves three Zabbix apt sources in place, two of them new:
zabbix-release, the final 8.0 packageszabbix-unstable, where Zabbix publishes test builds before they’re marked stablezabbix-tools, for extra utilities, already there from the 7.0 release package
On my boxes the only 8.0 builds were in unstable, so that’s where the candidate came from:
zabbix-server-mysql:
Installed: 1:7.0.32-1+ubuntu26.04
Candidate: 2:8.0.0~rc2-1+ubuntu26.04
Version table:
2:8.0.0~rc2-1+ubuntu26.04 500
500 https://repo.zabbix.com/zabbix/8.0/unstable/ubuntu resolute/main amd64 Packages
If your candidate also comes from .../8.0/unstable/..., you’re about to install a build Zabbix hasn’t marked stable yet. That’s fine for a lab, but on a production server I’d stop here and wait until apt-cache policy shows the candidate coming from the release tree. The commands don’t change either way. The packages carry an epoch of 2: against 7.0’s 1:, so apt always treats 8.0 as newer.
Upgrade only what’s installed. Swap mysql for pgsql in the server package name if that’s your database, and add zabbix-agent or zabbix-proxy-* packages if this box runs them. The two -o options keep any config file you’ve edited, which is what I’d answer at the prompt anyway:
sudo apt install --only-upgrade -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold zabbix-server-mysql zabbix-frontend-php zabbix-agent2 zabbix-sql-scripts 'zabbix-agent2-plugin-*'
The 'zabbix-agent2-plugin-*' glob is safe here because --only-upgrade skips plugins that aren’t installed; apt printed a “Skipping” line for each of them. The web server config package came along as a dependency, and dpkg kept my edited server config:
The following additional packages will be installed:
zabbix-apache-conf
The following packages will be upgraded:
zabbix-agent2 zabbix-apache-conf zabbix-frontend-php zabbix-server-mysql
zabbix-sql-scripts
5 upgraded, 0 newly installed, 0 to remove and 5 not upgraded.
...
Setting up zabbix-server-mysql (2:8.0.0~rc2-1+ubuntu26.04) ...
Configuration file '/etc/zabbix/zabbix_server.conf'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
==> Keeping old config file as default.
Setting up zabbix-sql-scripts (2:8.0.0~rc2-1+ubuntu26.04) ...
Setting up zabbix-frontend-php (2:8.0.0~rc2-1+ubuntu26.04) ...
update-alternatives: renaming zabbix-frontend-font link from /usr/share/zabbix/assets/fonts/graphfont.ttf to /usr/share/zabbix/ui/assets/fonts/graphfont.ttf
Setting up zabbix-agent2 (2:8.0.0~rc2-1+ubuntu26.04) ...
Installing new version of config file /etc/zabbix/zabbix_agent2.conf ...
...
Setting up zabbix-apache-conf (2:8.0.0~rc2-1+ubuntu26.04) ...
Installing new version of config file /etc/zabbix/apache.conf ...
dpkg made a different call for each of the three config files, and each call follows from whether the file had been edited:
zabbix_server.conf: edited, so kept/etc/zabbix/apache.conf: stock, so replacedzabbix_agent2.conf: stock on this box, so replaced
Keeping zabbix_server.conf is right, because the 8.0 file only adds commented options (the new HistoryProvider setting among them) and your DBPassword lives in yours. The exception is Elasticsearch history: 8.0 deprecates HistoryStorageURL, HistoryStorageTypes and HistoryStorageDateIndex in favour of HistoryProvider, and the two styles can’t be mixed, so read the upgrade notes if you set any of them. The replaced apache.conf is how the new Alias /zabbix /usr/share/zabbix/ui landed. Had you edited that file, dpkg would keep your copy, and you’d get the same “Manual intervention” page I hit on Rocky. An agent config where you’ve set Server= or Hostname= counts as edited, so dpkg keeps that one too.
Restart Apache so it loads the new alias, then start Zabbix. If your frontend runs on Nginx, restart nginx instead; I only ran Apache on the Ubuntu boxes:
sudo systemctl restart apache2
sudo systemctl start zabbix-server zabbix-agent2
The schema upgrade runs inside the server process on first start, and the log counts it up from 1% to 100%. Watch for the start and the end of it.
sudo grep -E 'current database version|required mandatory|automatic database upgrade|fully completed' /var/log/zabbix/zabbix_server.log | tail -4
On Ubuntu 26.04 it took 9.4 seconds from start to finish, and 24.04 took 9.5. The two version numbers are the schema’s, not the package’s, so 07050196 is what 8.0 expects:
43288:20261023:123902.170 current database version (mandatory/optional): 07000000/07000030
43288:20261023:123902.170 required mandatory version: 07050196
43288:20261023:123902.171 starting automatic database upgrade
43288:20261023:123911.583 database upgrade fully completed
Do not restart the server while that counter is still running. On a big database it can take a long time, and the tail -f on the log in a second terminal that Zabbix recommends is how you know it’s still working rather than hung.
Upgrading Zabbix on Rocky Linux 10
On Rocky the repository swap is cleaner than on Ubuntu, because the 8.0 release RPM replaces the 7.0 one outright and leaves no stale repo file. My Rocky box ran PostgreSQL and Nginx with SELinux enforcing, much like the setup in our Zabbix 7.0 install guide for Rocky Linux. Swap the release package first:
sudo rpm -Uvh https://repo.zabbix.com/zabbix/8.0/release/rocky/10/noarch/zabbix-release-latest-8.0.el10.noarch.rpm
sudo dnf clean all
On Rocky Linux 9 the package name and path end in 9 and el9 instead, and that is the one I used on the Rocky 9 box. Installing the EL10 package there would point dnf at EL10 builds:
sudo rpm -Uvh https://repo.zabbix.com/zabbix/8.0/release/rocky/9/noarch/zabbix-release-latest-8.0.el9.noarch.rpm
sudo dnf clean all
On the Rocky 10 box, rpm swapped the release package in one transaction, so there’s nothing left over to delete:
Updating / installing...
zabbix-release-8.0-0.1.el10 ########################################
Cleaning up / removing...
zabbix-release-7.0-7.el10 ########################################
AlmaLinux has its own tree in the same repository (.../8.0/release/alma/10/...), but I only ran the Rocky one. For the packages themselves I didn’t use the dnf install ... 'zabbix-agent2-plugin-*' line from Zabbix’s page: dnf install with that glob installs every agent 2 plugin, including ones you never had. A dry run on my box wanted six plugins I’d never installed, nine packages with their dependencies. dnf upgrade with a glob only touches what’s already there:
sudo dnf -y upgrade 'zabbix-*'
Nine packages moved, all from the zabbix-unstable repo on my box, which is the same situation as on Ubuntu. The two warnings at the end are the part to read.
zabbix-agent2 x86_64 2:8.0.0-rc2.release1.el10 zabbix-unstable 6.6 M
zabbix-nginx-conf noarch 2:8.0.0-rc2.release1.el10 zabbix-unstable 18 k
zabbix-selinux-policy x86_64 2:8.0.0-rc2.release1.el10 zabbix-unstable 326 k
zabbix-selinux-policy-main x86_64 2:8.0.0-rc2.release1.el10 zabbix-unstable 341 k
zabbix-server-pgsql x86_64 2:8.0.0-rc2.release1.el10 zabbix-unstable 2.9 M
zabbix-sql-scripts noarch 2:8.0.0-rc2.release1.el10 zabbix-unstable 9.5 M
zabbix-web noarch 2:8.0.0-rc2.release1.el10 zabbix-unstable 25 M
zabbix-web-deps noarch 2:8.0.0-rc2.release1.el10 zabbix-unstable 11 k
zabbix-web-pgsql noarch 2:8.0.0-rc2.release1.el10 zabbix-unstable 10 k
...
warning: /etc/nginx/conf.d/zabbix.conf created as /etc/nginx/conf.d/zabbix.conf.rpmnew
warning: /etc/zabbix/zabbix_server.conf created as /etc/zabbix/zabbix_server.conf.rpmnew
rpm kept both files I’d edited and wrote the package versions next to them as .rpmnew. For zabbix_server.conf that’s harmless: diffing the active lines showed only my own DBHost and DBPassword, so I kept mine and deleted the .rpmnew. The Nginx one is the reason the next section exists. Restart the web server and PHP-FPM so they load the new frontend config, then start the server and watch the schema upgrade. Use httpd in place of nginx if your frontend runs on Apache:
sudo systemctl restart nginx php-fpm
sudo systemctl start zabbix-server zabbix-agent2
sudo grep -E 'required mandatory|automatic database upgrade|fully completed' /var/log/zabbix/zabbix_server.log | tail -3
PostgreSQL took 28.4 seconds for the same schema change that MariaDB did in under 10, on a database of roughly the same size:

SELinux stayed enforcing the whole time, and ausearch -m avc -ts recent came back with <no matches> after the upgrade. The zabbix-selinux-policy-main package in that transaction is the EL10 policy Zabbix now ships; the 7.0 packages on my Rocky 10 box already had it, so for me it was an ordinary update.
Getting past “Manual intervention is required to complete upgrade”
With the server upgraded, the Rocky frontend returned a 404 with this page instead of the login screen. If you run Apache and never edited its Zabbix config, try a restart of httpd (or apache2) and php-fpm first: on the Rocky 9 box the stock Apache file had already been updated, and the page only went away once httpd reloaded it. Don’t run the sed below on an Apache file that already says /usr/share/zabbix/ui, or you’ll get /ui/ui.

Since 7.2, the packages install the frontend PHP files under /usr/share/zabbix/ui instead of /usr/share/zabbix, and they leave a small stub at the old location that prints this page. My Nginx config still had root /usr/share/zabbix, because I’d edited listen and server_name in it at install time, and rpm won’t overwrite an edited config. Diff the kept file against the .rpmnew to see it.
sudo diff /etc/nginx/conf.d/zabbix.conf /etc/nginx/conf.d/zabbix.conf.rpmnew
Apart from my two edits, the paths are the whole story, plus a client_max_body_size 5m line the new file adds:
2,3c2,3
< listen 80;
< server_name box2;
---
> # listen 8080;
> # server_name example.com;
5c5
< root /usr/share/zabbix;
---
> root /usr/share/zabbix/ui;
8a9,10
> client_max_body_size 5m;
>
41,43c43,45
< fastcgi_param DOCUMENT_ROOT /usr/share/zabbix;
< fastcgi_param SCRIPT_FILENAME /usr/share/zabbix$fastcgi_script_name;
< fastcgi_param PATH_TRANSLATED /usr/share/zabbix$fastcgi_script_name;
---
> fastcgi_param DOCUMENT_ROOT /usr/share/zabbix/ui;
> fastcgi_param SCRIPT_FILENAME /usr/share/zabbix/ui$fastcgi_script_name;
> fastcgi_param PATH_TRANSLATED /usr/share/zabbix/ui$fastcgi_script_name;
The stub page itself prints the fix, and it’s the one I used: rewrite every /usr/share/zabbix in your file to /usr/share/zabbix/ui, which keeps your listen and server_name lines. You already have a copy in /opt/zabbix-backup from earlier. This is the Rocky path; on Ubuntu, /etc/nginx/conf.d/zabbix.conf is a symlink to /etc/zabbix/nginx.conf, so run the sed on /etc/zabbix/nginx.conf instead or you replace the link with a plain file. I only tested the Rocky file.
sudo sed -i 's:/usr/share/zabbix:/usr/share/zabbix/ui:g' /etc/nginx/conf.d/zabbix.conf
sudo nginx -t
sudo systemctl restart nginx
Run the sed once only. A second run turns the paths into /usr/share/zabbix/ui/ui, so check the result instead of repeating it:
sudo grep -nE 'root|fastcgi_param\s+(DOCUMENT_ROOT|SCRIPT_FILENAME)' /etc/nginx/conf.d/zabbix.conf
Every line should contain /usr/share/zabbix/ui. If one doesn’t, edit it by hand rather than running the sed again:
5: root /usr/share/zabbix/ui;
41: fastcgi_param DOCUMENT_ROOT /usr/share/zabbix/ui;
42: fastcgi_param SCRIPT_FILENAME /usr/share/zabbix/ui$fastcgi_script_name;
Once that’s in place, the login page is back, and you can delete the .rpmnew. Leaving it doesn’t break anything, because Nginx only reads files ending in .conf, but the next upgrade will just write another one next to it.
Confirming the upgrade worked
Three checks tell you the server, the schema and the frontend all agree. Start with the binary and the API, which answers without a login.
zabbix_server -V | head -1
curl -s -X POST -H 'Content-Type: application/json-rpc' -d '{"jsonrpc":"2.0","method":"apiinfo.version","params":{},"id":1}' http://localhost/zabbix/api_jsonrpc.php
On the Rocky box Nginx serves Zabbix at the site root, so there the API sits at /api_jsonrpc.php on the name in your server_name, without the /zabbix prefix. The API reports a plain 8.0.0 even though the server binary says which build it is:
zabbix_server (Zabbix) 8.0.0rc2
{"jsonrpc":"2.0","result":"8.0.0","id":1}
Before the upgrade, the System information report (Reports, then System information) showed both halves at 7.0. I took this screenshot just before stopping the server:

After it, the same report shows the server and frontend at the same 8.0 build, the server running, and a new Zabbix server ID row. The host, template and item counts are the same as before, which is the quickest sign the schema upgrade didn’t lose configuration:

History survived too: the history table on the Ubuntu box had 390 rows before the upgrade and 447 a minute after it, so old values were kept and new ones were already arriving. Log in again after the upgrade rather than reusing an open tab, and clear the browser cache if a page looks broken, since 8.0 ships new fonts and themes. The Global view dashboard on the Rocky box also raised an information-level problem, “Zabbix server: Version has changed”, which is the stock template noticing the new version and nothing to fix:

The new APM entry in the left menu is the OpenTelemetry support that came with 8.0. It needs a ClickHouse data source and a proxy to collect traces, so it stays empty after an upgrade until you set those up. Templates and media types aren’t upgraded either, which matters if you use webhooks: 8.0’s versions verify TLS certificates by default, and you’ll only get that once you import them yourself, as the 8.0 upgrade notes explain.
Rolling back to 7.0 on Ubuntu
If you took a VM snapshot, restoring it is the rollback, and that’s what I’d do. Without one, you put the 7.0 packages back and restore the dump, because 7.0 can’t read an 8.0 schema. I tested this on the Ubuntu 26.04 box and needed three attempts, so the steps below are assembled from those runs rather than one clean pass. I did not test a rollback on Rocky. This is the order the attempts point to:
- Put the 7.0 apt source back
- Pick Zabbix’s own 7.0 build, not Ubuntu’s
- Remove the 8.0 frontend packages, then downgrade
- Restore the dump and the server config
- Delete the 8.0 apt sources
Each step exists because skipping it broke something on one of my attempts, and the two worst failures have their own sections after the commands.
Stop Zabbix, then put the 7.0 source back with the release package you downloaded earlier. --force-confmiss is what makes dpkg recreate zabbix.sources; without it dpkg respects the fact that you deleted it, and apt never sees the 7.0 repository:
sudo systemctl stop zabbix-server zabbix-agent2
cd ~
. /etc/os-release
sudo dpkg -i --force-confmiss "zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
sudo apt update
Why not just ask apt for any 7.0? Because on 26.04 the Ubuntu archive ships its own zabbix-server-mysql at 1:7.0.22+dfsg-1, and my first version filter grabbed that one. Matching on +ubuntu in the version string selects Zabbix’s own build.
ZBX70=$(apt-cache madison zabbix-server-mysql | awk '$3 ~ /^1:7\.0\..*\+ubuntu/ {print $3; exit}')
echo "$ZBX70"
It printed the latest 7.0 build Zabbix publishes for that release. If yours ends in +dfsg instead, the 7.0 source isn’t active, so go back to the dpkg -i step:
1:7.0.32-1+ubuntu26.04
Remove the 8.0 frontend and web server config first, then install the 7.0 set in one go. Doing it in one apt install without the removal fails, which is the first of the two errors below:
sudo apt remove -y zabbix-apache-conf zabbix-frontend-php
sudo apt install -y --allow-downgrades -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold zabbix-server-mysql="$ZBX70" zabbix-sql-scripts="$ZBX70" zabbix-agent2="$ZBX70" zabbix-frontend-php="$ZBX70" zabbix-apache-conf="$ZBX70"
Then recreate the database from the dump, put your server config back and start everything. On my 4 MB dump the restore took 15 seconds.
sudo mariadb -e "DROP DATABASE zabbix; CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;"
zcat /opt/zabbix-backup/zabbix-70.sql.gz | sudo mariadb zabbix
sudo cp /opt/zabbix-backup/zabbix_server.conf /etc/zabbix/zabbix_server.conf
sudo systemctl restart apache2
sudo systemctl start zabbix-server zabbix-agent2
The last step is the one people forget. The 8.0 sources are still enabled, so the next apt upgrade would put 8.0 straight back. Delete them and confirm the candidate is 7.0 again.
sudo rm -f /etc/apt/sources.list.d/zabbix-release.sources /etc/apt/sources.list.d/zabbix-unstable.sources
sudo apt update
apt-cache policy zabbix-server-mysql | head -3
Installed and candidate match, and the API answered 7.0.32 again:
zabbix-server-mysql:
Installed: 1:7.0.32-1+ubuntu26.04
Candidate: 1:7.0.32-1+ubuntu26.04
That’s the box back where it started, with the 7.0 schema and the 7.0 frontend. The zabbix-tools.sources file stays as it was, because the 7.0 release package ships it too and it carries no server packages.
trying to overwrite ‘/usr/share/zabbix/browserwarning.php’, which is also in package zabbix-apache-conf
My first rollback downgraded all five packages in one apt install, and dpkg stopped halfway:
dpkg: error processing archive /var/cache/apt/archives/zabbix-frontend-php_1%3a7.0.32-1+ubuntu26.04_all.deb (--unpack):
trying to overwrite '/usr/share/zabbix/browserwarning.php', which is also in package zabbix-apache-conf (2:8.0.0~rc2-1+ubuntu26.04)
The stub files that print the “Manual intervention” page belong to the 8.0 web server package, and they sit exactly where the 7.0 frontend wants to put its real files. The server package had already gone back to 7.0, the frontend hadn’t, and the half-downgraded box served “The Zabbix database version does not match current requirements” from the API. Removing zabbix-apache-conf and zabbix-frontend-php before installing, as above, avoids it. If you’re already in that state, sudo dpkg --configure -a --force-confold finishes the packages that did unpack (without the option it stops at the zabbix_server.conf prompt), and then the remove and install steps go through.
The rollback installed Ubuntu’s own Zabbix 7.0.22
On my second attempt I’d reinstalled the 7.0 release package without --force-confmiss, so there was no 7.0 source, and apt-cache madison only listed the 8.0 builds plus the archive’s 1:7.0.22+dfsg-1 from resolute/universe. A filter on ^1:7\.0\. picked that, the install failed, and the 8.0 server, which was still installed, started on the freshly restored 7.0 dump and began upgrading it again. Check that echo "$ZBX70" ends in +ubuntu plus your release before you run the install, and make sure the server package really is 7.0 before you restore the dump.
What I still don’t know
My test databases were small, a few hundred history rows and a single monitored host, and that limits what these notes can promise. These are the things I’d want answered before doing this on a large production server:
- How long the schema upgrade takes on hundreds of gigabytes of history
- Whether the final packages land in the
releasetree with the same file layout - The TimescaleDB step for the new
history_jsonhypertable, which I didn’t run - How 7.0 proxies behave against an 8.0 server over a real WAN
On the proxy point, Zabbix’s compatibility notes say an 8.0 server still accepts data from proxies as old as the previous LTS, so 7.0, 7.2 and 7.4. It runs them in a limited mode with configuration updates switched off, so I’d upgrade the server first and the proxies right after it rather than run mixed for long. If you’re starting fresh instead of upgrading, the Zabbix 8.0 install on Ubuntu 26.04 and the 8.0 install on Rocky Linux 10 skip all of the above. For servers you’ll keep on the LTS a while longer, the Zabbix 7.0 guide for Ubuntu is still the one I’d follow.