TechnitiumSoftware/DnsServer · error · DnsServerException
Cannot convert to NSEC3: the zone must be signed with NSEC f
Error message
Cannot convert to NSEC3: the zone must be signed with NSEC for conversion.
What it means
Thrown by PrimaryZone.ConvertToNSec3 when the zone's DNSSEC status is not SignedWithNSEC. The library only permits converting a zone that is currently signed with plain NSEC into the NSEC3 variant; going straight from Unsigned to NSEC3 (or re-converting a zone already on NSEC3) is rejected so the existing NSEC chain can be cleanly disabled first.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:726
foreach (AuthZone zone in zones)
{
if (!zone.IsEmpty)
nonEmptyZones.Add(zone);
}
EnableNSec(nonEmptyZones);
_dnssecStatus = AuthZoneDnssecStatus.SignedWithNSEC;
}
TriggerNotify();
}
public void ConvertToNSec3(ushort iterations, byte saltLength)
{
if (_dnssecStatus != AuthZoneDnssecStatus.SignedWithNSEC)
throw new DnsServerException("Cannot convert to NSEC3: the zone must be signed with NSEC for conversion.");
if (iterations > 50)
throw new ArgumentOutOfRangeException(nameof(iterations), "NSEC3 iterations valid range is 0-50");
if (saltLength > 32)
throw new ArgumentOutOfRangeException(nameof(saltLength), "NSEC3 salt length valid range is 0-32");
lock (_dnssecUpdateLock)
{
IReadOnlyList<AuthZone> zones = _dnsServer.AuthZoneManager.GetApexZoneWithSubDomainZones(_name);
DisableNSec(zones);
EnableNSec3(zones, iterations, saltLength);
_dnssecStatus = AuthZoneDnssecStatus.SignedWithNSEC3;
}
TriggerNotify();View on GitHub (pinned to d0484b6c1e)
Solutions
- If the zone is Unsigned, sign it first with NSEC (call SignZone with useNSec3=false), then call ConvertToNSec3.
- If the zone is already SignedWithNSEC3 and you want to change salt/iterations, call UpdateNSec3Parameters instead of ConvertToNSec3.
- Guard the call with a check on the zone's DnssecStatus property before invoking ConvertToNSec3.
Example fix
// before
zone.ConvertToNSec3(iterations: 2, saltLength: 8);
// after
if (zone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)
zone.SignZone(keys, dnsKeyTtl, useNSec3: false);
if (zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC)
zone.ConvertToNSec3(iterations: 2, saltLength: 8);
else if (zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3)
zone.UpdateNSec3Parameters(iterations: 2, saltLength: 8); Defensive patterns
Strategy: validation
Validate before calling
// Verify the zone is on NSEC before converting to NSEC3
if (zone.DnssecStatus != AuthZoneDnssecStatus.SignedWithNSEC)
{
if (zone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)
zone.SignZone(keys, dnsKeyTtl, useNSec3: false);
else if (zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3)
{
zone.UpdateNSec3Parameters(iterations, saltLength);
return;
}
}
zone.ConvertToNSec3(iterations, saltLength); Type guard
static bool CanConvertToNSec3(ApexZone zone) =>
zone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC; Try / catch
try
{
zone.ConvertToNSec3(iterations, saltLength);
}
catch (DnsServerException ex) when (ex.Message.Contains("must be signed with NSEC for conversion"))
{
// sign with NSEC first, then retry; or route to UpdateNSec3Parameters
} Prevention
- Always read zone.DnssecStatus before invoking a DNSSEC state-transition method.
- Treat NSEC->NSEC3 as a one-way conversion; use UpdateNSec3Parameters to adjust an existing NSEC3 zone.
When it happens
Trigger: Calling ConvertToNSec3(iterations, saltLength) on a zone whose DnssecStatus is Unsigned, or calling it again on a zone whose DnssecStatus is already SignedWithNSEC3.
Common situations: A developer enables DNSSEC signing and assumes NSEC3 is the default, calling ConvertToNSec3 without first calling SignZone with useNSec3=false. Or scripting a 're-sign as NSEC3' routine that fires against an already-NSEC3 zone after a reload.
Related errors
- Cannot update NSEC3 parameters: the zone must be signed with
- NSEC3 salt length valid range is 0-32
- NSEC3 iterations valid range is 0-50
- The primary zone must be signed.
- The zone must be signed.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/97d85058b53990b5.
Report an issue: GitHub.