[BUG] migrate_conf_to_ubuntu_26.04.sh: Bind section breaks named when orphaned named.conf.default-zones exists (duplicate zone ".")

Hi all,

This is a follow-up to my earlier report ([SOLVED] File Manager “Unknown error” after Ubuntu 26.04 upgrade — “No compatible key exchange algorithms found”) — same server, same upgrade. The official migration script (/usr/local/hestia/install/upgrade/manual/migrate_conf_to_ubuntu_26.04.sh) fixed the File Manager as documented, but its Bind section broke named, and I believe the guard logic has a gap worth reporting.

What happened

After running the script, bind9 fails to start:

$ sudo named-checkconf
/etc/bind/named.conf.default-zones:2: zone '.': already exists previous definition: /etc/bind/named.conf.root-hints:2
named[...]: loading configuration: failure
named[...]: exiting (due to fatal error)
systemd[1]: named.service: Failed with result 'exit-code'.

Root cause

On systems upgraded from an older Ubuntu/Debian, the unowned leftover /etc/bind/named.conf.default-zones still exists on disk:

$ dpkg -S /etc/bind/named.conf.default-zones /etc/bind/named.conf.root-hints
dpkg-query: no path found matching pattern /etc/bind/named.conf.default-zones
bind9: /etc/bind/named.conf.root-hints

named.conf.default-zones is not owned by any package (the bind9 package ships named.conf.root-hints instead), but nothing deletes the old file during the OS upgrade.

The script’s two Bind edits have asymmetric guards:

# Edit 1 — only runs if the orphan file is GONE:
if [[ ! -f /etc/bind/named.conf.default-zones ]] && grep -q "include.*named.conf.default-zones" ...

# Edit 2 — runs whenever root-hints exists:
if [[ -f /etc/bind/named.conf.root-hints ]] && ! grep -q 'include.*named.conf.root-hints' ...

On upgraded systems the orphan file still exists → Edit 1 is skipped (the default-zones include stays) → Edit 2 adds the root-hints include → both define zone "." → named refuses to start.

Suggested fix

Make Edit 1 independent of file existence — remove the include whenever the line is present (and ideally delete the unowned file too):

if grep -q "include.*named.conf.default-zones" /etc/bind/named.conf 2> /dev/null; then
        echo "[ + ] Removing the default-zones include from named.conf"
        sed -i "/^include.*named.conf.default-zones/d" /etc/bind/named.conf
        _bind_changed=true
fi

Alternatively, guard Edit 2 on Edit 1 having actually run (or on the default-zones include being absent), so the two can never coexist.

Workaround (for anyone hitting this now)

# comment out or delete the default-zones include in /etc/bind/named.conf,
# then:
sudo named-checkconf
sudo systemctl reset-failed named
sudo systemctl start named

Note the default-zones include references zone files (db.local, db.127, …) that don’t exist on upgraded systems anyway, so removing it loses nothing — named.conf.root-hints (the package-owned file) provides the root hint zone and is the correct one to keep.

Environment

  • HestiaCP 1.10.5-1+ubuntu26.04
  • Ubuntu 26.04 (aarch64), upgraded from 24.04
  • bind9 package owns named.conf.root-hints; named.conf.default-zones is an untracked leftover

In my tests, when upgrading from Debian 12 to 13 or Ubuntu 24.04 to 26.04, named.conf.default-zones was always removed, which is why I added the check for the file’s existence.

Anyway, I’ve created this PR to always remove the default-zones include from named.conf.

Excellent, thank you!