MySQL won’t start after a Debian 12 upgrade: cause and fix

The symptom: mysql.service in a failed state

MySQL won’t start: the service shows as failed and the log reports the error Can't read dir of '/etc/mysql/mariadb.conf.d/':

MySQL won't start: a cylinder representing a database with an orange warning circle beside it
# service mysql status
× mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; preset: enabled)
     Active: failed (Result: exit-code)
     Status: "Server startup in progress"

mysqld: Can't read dir of '/etc/mysql/mariadb.conf.d/' (OS errno 2 - No such file or directory)
mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/mysql/my.cnf at line 29.
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
systemd[1]: Failed to start mysql.service - MySQL Community Server.

Checking the installed packages, MySQL is there as expected (mysql-community-server 8.0 packages from the official Oracle repository):

dpkg -l | grep mysql

The cause: the my.cnf alternative points to mariadb.cnf

On Debian the file /etc/mysql/my.cnf is not a real file but a link managed by update-alternatives. Several packages can register their own version and, in automatic mode, the one with the highest priority wins.

During the upgrade the mariadb-common package was installed (and later removed), which registers /etc/mysql/mariadb.cnf with priority 500, higher than /etc/mysql/mysql.cnf (priority 300). The package was removed but not fully purged (state rc), so its configuration stayed active. On line 29 of that file there is an include of /etc/mysql/mariadb.conf.d/, a directory that does not exist. MySQL reads the configuration, cannot find the directory and stops, which is why MySQL won’t start.

Good news: the data in /var/lib/mysql has not been touched. It is only a configuration problem.

Diagnosis: check where my.cnf points

ls -l /etc/mysql/my.cnf /etc/alternatives/my.cnf
update-alternatives --display my.cnf
sed -n '25,32p' /etc/mysql/my.cnf
dpkg -l | grep -i mariadb

If this is the problem, the output will look like this:

/etc/alternatives/my.cnf -> /etc/mysql/mariadb.cnf
/etc/mysql/my.cnf -> /etc/alternatives/my.cnf

my.cnf - modalità automatica
  la versione migliore del collegamento è /etc/mysql/mariadb.cnf
  il collegamento attualmente punta a /etc/mysql/mariadb.cnf
/etc/mysql/mariadb.cnf - priorità 500
/etc/mysql/my.cnf.fallback - priorità 100
/etc/mysql/mysql.cnf - priorità 300

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mariadb.conf.d/

rc  mariadb-common   1:10.11.18-0+deb12u1   all   MariaDB common configuration files

Step-by-step fix

1. Back up the configuration

cp -a /etc/mysql /root/etc-mysql-backup-$(date +%F)

2. Remove the mariadb-common leftovers

The purge removes mariadb.cnf and its entry in update-alternatives:

apt purge mariadb-common

3. Point my.cnf back to mysql.cnf

update-alternatives --remove my.cnf /etc/mysql/mariadb.cnf 2>/dev/null
update-alternatives --set my.cnf /etc/mysql/mysql.cnf

4. Check the configuration

update-alternatives --display my.cnf
cat /etc/mysql/my.cnf
my_print_defaults mysqld

Now my.cnf must point to /etc/mysql/mysql.cnf and include /etc/mysql/conf.d/ and /etc/mysql/mysql.conf.d/. If my_print_defaults mysqld prints the parameters without errors, the configuration is correct.

5. Start MySQL

systemctl start mysql
systemctl status mysql
journalctl -u mysql -n 50 --no-pager

If MySQL won’t start and my.cnf is not a symbolic link

If /etc/mysql/my.cnf is a regular file or /etc/mysql/mysql.cnf does not exist, you can recreate the configuration by hand:

mv /etc/mysql/my.cnf /etc/mysql/my.cnf.mariadb.bak
cat > /etc/mysql/my.cnf <<'EOF'
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
EOF
mkdir -p /etc/mysql/conf.d
systemctl start mysql

Quick temporary fix when MySQL won’t start

If you need to bring the database back online right away, just create the missing directory. It is only a stopgap, though. MySQL would keep reading the configuration meant for MariaDB. Better to apply the complete fix as soon as possible.

mkdir /etc/mysql/mariadb.conf.d && systemctl start mysql

How to stop it happening again

It is worth finding out which upgrade installed MariaDB, by looking at the apt history:

grep -i -B3 -A3 mariadb /var/log/apt/history.log*

To stop mariadb-common being reinstalled in the future you can block it with an APT pin at a negative priority:

cat > /etc/apt/preferences.d/no-mariadb <<'EOF'
Package: mariadb-*
Pin: release *
Pin-Priority: -1
EOF

After every major upgrade it is also good practice to check the state of the alternative with update-alternatives --display my.cnf. Before the next upgrade, read the Debian 12 release notes for known issues. A related case is MySQL 5.7 in Docker protected with nftables.

Frequently asked questions

Will I lose my database data?

No. The problem only concerns the configuration files in /etc/mysql; the data in /var/lib/mysql stays intact.

Why did Debian choose mariadb.cnf?

Because the my.cnf alternative was in automatic mode and mariadb.cnf has priority 500, higher than the 300 of mysql.cnf. With update-alternatives --set the choice becomes manual and no longer changes by itself.

Does it apply to Ubuntu too?

Yes, the update-alternatives mechanism for my.cnf is the same on Ubuntu and on the other Debian-derived distributions.

Conclusion

The error “Can’t read dir of /etc/mysql/mariadb.conf.d/” after a Debian upgrade does not mean MySQL is damaged. It means a leftover MariaDB configuration has stayed active through update-alternatives. By removing mariadb-common with apt purge and setting my.cnf back to mysql.cnf, MySQL works normally again. If MySQL won’t start after an upgrade, check update-alternatives first.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

WordPress Cookie Notice by Real Cookie Banner