TechnitiumSoftware/DnsServer · error · DnsServerException
Cannot unsign zone: the is zone not signed.
Error message
Cannot unsign zone: the is zone not signed.
What it means
Thrown by PrimaryZone.UnsignZone when _dnssecStatus == AuthZoneDnssecStatus.Unsigned — i.e., the zone is not signed, so there is nothing to unsign. The guard raises DnsServerException before gathering the apex/sub-domain zone list. (Message text 'the is zone not signed' is a verbatim source wording.)
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:660
foreach (KeyValuePair<string, Dictionary<DnsResourceRecordType, List<DnsResourceRecord>>> deletedRecordGroup in deletedRecordGroups)
{
AuthZone zone = _dnsServer.AuthZoneManager.GetAuthZone(_name, deletedRecordGroup.Key);
foreach (KeyValuePair<DnsResourceRecordType, List<DnsResourceRecord>> deletedRecordEntry in deletedRecordGroup.Value)
{
foreach (DnsResourceRecord deletedRecord in deletedRecordEntry.Value)
zone.AddRecord(deletedRecord, out _, out _);
}
}
throw;
}
}
public void UnsignZone()
{
if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)
throw new DnsServerException("Cannot unsign zone: the is zone not signed.");
List<DnsResourceRecord> deletedRecords = new List<DnsResourceRecord>();
IReadOnlyList<AuthZone> zones = _dnsServer.AuthZoneManager.GetApexZoneWithSubDomainZones(_name);
foreach (AuthZone zone in zones)
{
deletedRecords.AddRange(zone.RemoveAllDnssecRecords());
if (zone is SubDomainZone subDomainZone)
{
if (zone.IsEmpty)
_dnsServer.AuthZoneManager.RemoveSubDomainZone(zone.Name); //remove empty sub zone
else
subDomainZone.AutoUpdateState();
}
}
Timer dnssecTimer = _dnssecTimer;View on GitHub (pinned to d0484b6c1e)
Solutions
- Check zone.DnssecStatus != Unsigned before calling UnsignZone.
- Treat 'already unsigned' as a no-op in the caller rather than an error.
- Guard concurrent unsign operations to avoid racing into Unsigned state.
Example fix
// before
zone.UnsignZone(); // may throw if unsigned
// after
if (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)
zone.UnsignZone(); Defensive patterns
Strategy: try-catch
Validate before calling
if (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)
zone.UnsignZone(); Type guard
static bool CanUnsign(AuthZone z) => z.DnssecStatus != AuthZoneDnssecStatus.Unsigned;
Try / catch
try { zone.UnsignZone(); }
catch (DnsServerException ex) when (ex.Message.Contains("not signed"))
{ /* already unsigned: treat as no-op */ } Prevention
- Check DnssecStatus != Unsigned before UnsignZone.
- Treat already-unsigned as a no-op in automation.
- Guard concurrent unsign to avoid state races.
When it happens
Trigger: Calling zone.UnsignZone() on an already-unsigned primary zone; double-unsign after a previous call; unsign after a failed sign that rolled back to Unsigned.
Common situations: UI 'Unsign' pressed on a zone that was never signed; automation that unsigns defensively without checking state.
Related errors
- Cannot sign zone: the zone is already signed.
- Cannot delete DNSSEC records.
- Cannot update DNSSEC records.
- Cannot update record: disabling records in a signed zones is
- Cannot update record: the record does not exists to be updat
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/89abd737ebfb3151.
Report an issue: GitHub.