TechnitiumSoftware/DnsServer · error · DnsServerException

Cannot convert to NSEC: the zone must be signed with NSEC3 f

Error message

Cannot convert to NSEC: the zone must be signed with NSEC3 for conversion.

What it means

Thrown by PrimaryZone.ConvertToNSec when _dnssecStatus != AuthZoneDnssecStatus.SignedWithNSEC3. Conversion is only defined from NSEC3 to NSEC; calling it on an Unsigned zone or an NSEC-signed zone is invalid. The guard raises DnsServerException before acquiring _dnssecUpdateLock or touching zone data.

Source

Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:698

            {
                lock (dnssecTimer)
                {
                    dnssecTimer.Dispose();
                    _dnssecTimer = null;
                }
            }

            _dnssecPrivateKeys = null;
            _dnssecStatus = AuthZoneDnssecStatus.Unsigned;

            CommitAndIncrementSerial(deletedRecords);
            TriggerNotify();
        }

        public void ConvertToNSec()
        {
            if (_dnssecStatus != AuthZoneDnssecStatus.SignedWithNSEC3)
                throw new DnsServerException("Cannot convert to NSEC: the zone must be signed with NSEC3 for conversion.");

            lock (_dnssecUpdateLock)
            {
                IReadOnlyList<AuthZone> zones = _dnsServer.AuthZoneManager.GetApexZoneWithSubDomainZones(_name);

                DisableNSec3(zones);

                //since zones were removed when disabling NSEC3; get updated non empty zones list
                List<AuthZone> nonEmptyZones = new List<AuthZone>(zones.Count);

                foreach (AuthZone zone in zones)
                {
                    if (!zone.IsEmpty)
                        nonEmptyZones.Add(zone);
                }

                EnableNSec(nonEmptyZones);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Check zone.DnssecStatus == SignedWithNSEC3 before calling ConvertToNSec.
  2. If the zone is Unsigned, sign with useNSec3=false directly instead of converting.
  3. If NSEC-signed already, no conversion is needed.

Example fix

// before
zone.ConvertToNSec(); // throws unless NSEC3-signed

// after
if (zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3)
    zone.ConvertToNSec();
Defensive patterns

Strategy: try-catch

Validate before calling

if (zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3)
    zone.ConvertToNSec();

Type guard

static bool CanConvertToNsec(AuthZone z) => z.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3;

Try / catch

try { zone.ConvertToNSec(); }
catch (DnsServerException ex) when (ex.Message.Contains("must be signed with NSEC3"))
{ /* wrong sign mode: sign with NSEC3 first, or no-op if already NSEC */ }

Prevention

When it happens

Trigger: zone.ConvertToNSec() on a zone that is Unsigned or SignedWithNSEC.

Common situations: Calling ConvertToNSec on a freshly signed NSEC zone by mistake; UI offering the conversion unconditionally; running the conversion in a sequence without verifying the prior sign mode.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/8758aa3718c71195. Report an issue: GitHub.