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/':

# 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.
Leave a Reply