TechnitiumSoftware/DnsServer · error · DnsServerException
Cannot publish DNSKEY: the key is already published.
Error message
Cannot publish DNSKEY: the key is already published.
What it means
Thrown inside the AddOrUpdate update delegate of PublishAllGeneratedKeys when a DNSKEY record being published already equals one present in the zone. The method merges new DNSKEY records with existing ones; an exact-match record means the key is already published, so it refuses rather than creating a duplicate RRset entry.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:1143
}
}
}
if (generatedPrivateKeys.Count == 0)
throw new DnsServerException("Cannot publish DNSKEY: no generated private keys were found.");
IReadOnlyList<DnsResourceRecord> dnsKeyRecords = _entries.AddOrUpdate(DnsResourceRecordType.DNSKEY, delegate (DnsResourceRecordType key)
{
return newDnsKeyRecords;
},
delegate (DnsResourceRecordType key, IReadOnlyList<DnsResourceRecord> existingRecords)
{
foreach (DnsResourceRecord existingRecord in existingRecords)
{
foreach (DnsResourceRecord newDnsKeyRecord in newDnsKeyRecords)
{
if (existingRecord.Equals(newDnsKeyRecord))
throw new DnsServerException("Cannot publish DNSKEY: the key is already published.");
}
}
List<DnsResourceRecord> dnsKeyRecords = new List<DnsResourceRecord>(existingRecords.Count + newDnsKeyRecords.Count);
dnsKeyRecords.AddRange(existingRecords);
dnsKeyRecords.AddRange(newDnsKeyRecords);
return dnsKeyRecords;
});
//update private key state before signing
uint propagationDelay = GetPropagationDelay();
foreach (DnssecPrivateKey privateKey in generatedPrivateKeys)
privateKey.SetState(DnssecPrivateKeyState.Published, dnsKeyTtl + propagationDelay);
List<DnsResourceRecord> addedRecords = new List<DnsResourceRecord>();View on GitHub (pinned to d0484b6c1e)
Solutions
- Before publishing, compare each Generated key's DNSKEY against the zone's existing DNSKEY records and skip duplicates.
- If duplicates exist from a bad restore, remove the stale DNSKEY records first, then publish.
- Make publish idempotent: catch the 'already published' condition and treat it as success for that key.
Example fix
// before
zone.PublishAllGeneratedKeys();
// after
var existingDnsKeys = zone.GetRecords(DnsResourceRecordType.DNSKEY) ?? Array.Empty<DnsResourceRecord>();
bool hasUnpublished = zone.DnssecPrivateKeys
.Where(k => k.State == DnssecPrivateKeyState.Generated)
.Any(k => !existingDnsKeys.Any(r => r.Equals(new DnsResourceRecord(zone.Name, DnsResourceRecordType.DNSKEY, DnsClass.IN, ttl, k.DnsKey))));
if (hasUnpublished)
zone.PublishAllGeneratedKeys(); Defensive patterns
Strategy: validation
Validate before calling
// Skip publishing keys whose DNSKEY is already in the zone
var existing = (zone.GetRecords(DnsResourceRecordType.DNSKEY) ?? Array.Empty<DnsResourceRecord>()).ToList();
var toPublish = zone.DnssecPrivateKeys
.Where(k => k.State == DnssecPrivateKeyState.Generated)
.Where(k => !existing.Any(r => r.RDATA.Equals(k.DnsKey)))
.ToList();
if (toPublish.Count > 0)
zone.PublishAllGeneratedKeys(); Type guard
static bool DnsKeyAlreadyPublished(IEnumerable<DnsResourceRecord> existing, DnssecPrivateKey key) =>
existing.Any(r => r.RDATA.Equals(key.DnsKey)); Try / catch
try
{
zone.PublishAllGeneratedKeys();
}
catch (DnsServerException ex) when (ex.Message.Contains("the key is already published"))
{
// one or more keys are already in the DNSKEY set; remove stale Generated entries or skip
} Prevention
- Before publishing, diff Generated keys' DNSKEY records against the zone's existing DNSKEY set.
- If a partial publish left stale state, remove the duplicate DNSKEY records before retrying.
When it happens
Trigger: Calling PublishAllGeneratedKeys when one or more Generated keys' DNSKEY records are byte-for-byte identical to DNSKEY records already in the zone (e.g. re-publishing after a partial publish or a reload that left stale DNSKEY records).
Common situations: A crash between marking a key Published and committing the DNSKEY set; importing a zone that already carried the DNSKEY; calling publish against a key whose DNSKEY was restored from backup.
Related errors
- Cannot publish DNSKEY: no generated private keys were found.
- The primary zone must be signed.
- Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.K
- Cannot update private key: no such private key was found.
- The zone must be signed.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/e1bfbe6582db63e5.
Report an issue: GitHub.