TechnitiumSoftware/DnsServer · warning · DnsServerException

Cannot update DNSKEY TTL value: one or more private keys hav

Error message

Cannot update DNSKEY TTL value: one or more private keys have state other than Ready or Active.

What it means

Thrown inside UpdateDnsKeyTtl() while iterating the zone's DNSSEC private keys under a lock. Only keys in DnssecPrivateKeyState.Ready or DnssecPrivateKeyState.Active are stable enough to re-sign a DNSKEY RRset whose TTL changed. Any key still in a transitional state (Generated, Published, or a rollover/publish/retire state) means the key set is mid-rollover and the TTL change cannot be applied atomically with a consistent signature.

Source

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

        }

        public void UpdateDnsKeyTtl(uint dnsKeyTtl)
        {
            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)
                throw new DnsServerException("The zone must be signed.");

            lock (_dnssecPrivateKeys)
            {
                foreach (KeyValuePair<ushort, DnssecPrivateKey> privateKeyEntry in _dnssecPrivateKeys)
                {
                    switch (privateKeyEntry.Value.State)
                    {
                        case DnssecPrivateKeyState.Ready:
                        case DnssecPrivateKeyState.Active:
                            break;

                        default:
                            throw new DnsServerException("Cannot update DNSKEY TTL value: one or more private keys have state other than Ready or Active.");
                    }
                }
            }

            if (!_entries.TryGetValue(DnsResourceRecordType.DNSKEY, out IReadOnlyList<DnsResourceRecord> dnsKeyRecords))
                throw new InvalidOperationException();

            DnsResourceRecord[] newDnsKeyRecords = new DnsResourceRecord[dnsKeyRecords.Count];

            for (int i = 0; i < dnsKeyRecords.Count; i++)
            {
                DnsResourceRecord dnsKeyRecord = dnsKeyRecords[i];
                newDnsKeyRecords[i] = new DnsResourceRecord(dnsKeyRecord.Name, DnsResourceRecordType.DNSKEY, DnsClass.IN, dnsKeyTtl, dnsKeyRecord.RDATA);
            }

            List<DnsResourceRecord> addedRecords = new List<DnsResourceRecord>();
            List<DnsResourceRecord> deletedRecords = new List<DnsResourceRecord>();

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Wait for the active key rollover to finish so every key reaches Ready or Active, then retry UpdateDnsKeyTtl.
  2. Inspect each private key's State via the DNSSEC key management API and advance or complete the rollover for any non-stable key before retrying.
  3. If a key is stuck in a transitional state due to a failed rollover, resolve/abort that key's rollover state, then retry the TTL update.

Example fix

// before
zone.UpdateDnsKeyTtl(desiredTtl); // throws mid-rollover

// after
if (AllKeysStable(zone)) // every key.State is Ready or Active
    zone.UpdateDnsKeyTtl(desiredTtl);
else
    Log.Warn("Skip DNSKEY TTL update: key rollover in progress");
Defensive patterns

Strategy: validation

Validate before calling

// Verify every private key is stable (Ready/Active) before updating TTL.
bool AllKeysStableForTtlUpdate(Zone zone) =>
    GetDnssecPrivateKeys(zone).All(k =>
        k.State == DnssecPrivateKeyState.Ready ||
        k.State == DnssecPrivateKeyState.Active);

if (AllKeysStableForTtlUpdate(zone))
    zone.UpdateDnsKeyTtl(desiredTtl);
else
    Log.Warn("DNSKEY TTL update skipped: a key rollover is in progress.");

Type guard

static bool CanUpdateDnsKeyTtlNow(Zone zone) =>
    GetDnssecPrivateKeys(zone).All(k =>
        k.State == DnssecPrivateKeyState.Ready ||
        k.State == DnssecPrivateKeyState.Active);

Try / catch

try { zone.UpdateDnsKeyTtl(ttl); }
catch (DnsServerException ex) when (ex.Message.Contains("state other than Ready or Active"))
{ Log.Warn($"Key rollover in progress; retry later: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling UpdateDnsKeyTtl during an active key rollover when at least one DnssecPrivateKey.State is neither Ready nor Active (e.g. Generated, Published, or a publish/retire phase). Triggered by changing the DNSKEY TTL while a scheduled KSK/ZSK rollover is in progress.

Common situations: Operator triggers an emergency TTL change during a routine ZSK pre-publication; automation that periodically normalizes DNSKEY TTLs collides with a rollover schedule; manually advancing key states leaves one key stuck in Published.

Related errors


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