{"record":{"id":"df84423eab9e0094","repo":"TechnitiumSoftware/DnsServer","slug":"automatic-rollover-is-not-supported-for-key-signin","errorCode":null,"errorMessage":"Automatic rollover is not supported for Key Signing Keys (KSK).","messagePattern":"Automatic rollover is not supported for Key Signing Keys \\(KSK\\)\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Dnssec/DnssecPrivateKey.cs","lineNumber":458,"sourceCode":"                    switch (_state)\n                    {\n                        case DnssecPrivateKeyState.Generated:\n                        case DnssecPrivateKeyState.Published:\n                        case DnssecPrivateKeyState.Ready:\n                        case DnssecPrivateKeyState.Active:\n                            if (_isRetiring)\n                                throw new InvalidOperationException(\"Zone Signing Key (ZSK) automatic rollover cannot be set since it is set to retire.\");\n\n                            break;\n\n                        default:\n                            throw new InvalidOperationException(\"Zone Signing Key (ZSK) automatic rollover cannot be set due to invalid key state.\");\n                    }\n                }\n                else\n                {\n                    if (value != 0)\n                        throw new NotSupportedException(\"Automatic rollover is not supported for Key Signing Keys (KSK).\");\n                }\n\n                _rolloverDays = value;\n            }\n        }\n\n        public DnsDNSKEYRecordData DnsKey\n        { get { return _dnsKey; } }\n\n        public ushort KeyTag\n        { get { return _dnsKey.ComputedKeyTag; } }\n\n        #endregion\n    }\n}\n","sourceCodeStart":440,"sourceCodeEnd":474,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Dnssec/DnssecPrivateKey.cs#L440-L474","documentation":"Thrown by RolloverDays setter when _keyType is not ZoneSigningKey (i.e. it is a Key Signing Key, KSK) and the value is non-zero. Automatic rollover is implemented only for ZSKs because KSK rollover has a parent-side DS coordination step this code path does not handle; any non-zero value on a KSK is therefore rejected.","triggerScenarios":"Assigning key.RolloverDays = N (N != 0) on a key whose _keyType == DnssecPrivateKeyType.KeySigningKey. The 0 case is explicitly allowed so serializers can write the default without error.","commonSituations":"Config restore or API call sets the same RolloverDays value on every DNSSEC key including the KSK; operator picks the KSK row in the UI and enables auto-rollover.","solutions":["Do not set RolloverDays on a KSK; automatic rollover is ZSK-only. Leave it at 0.","For KSK rollover use the manual DNSSEC rollover workflow (DS coordination) provided by the DNSSEC API.","In bulk key-config code, branch on key type and only assign RolloverDays for ZoneSigningKey."],"exampleFix":"// before\nforeach (var k in keys) k.RolloverDays = 30; // includes KSK\n\n// after\nforeach (var k in keys)\n    if (k.KeyType == DnssecPrivateKeyType.ZoneSigningKey)\n        k.RolloverDays = 30;\n    else\n        k.RolloverDays = 0; // KSK: rollover not supported","handlingStrategy":"validation","validationCode":"if (key.KeyType == DnssecPrivateKeyType.ZoneSigningKey)\n    key.RolloverDays = (ushort)days;\nelse if (days != 0)\n    throw new NotSupportedException(\"Automatic rollover is ZSK-only; use manual KSK rollover.\");","typeGuard":"static bool SupportsAutoRollover(DnssecPrivateKey k) =>\n    k.KeyType == DnssecPrivateKeyType.ZoneSigningKey;","tryCatchPattern":"try { key.RolloverDays = (ushort)days; }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"Key Signing Keys\"))\n{ /* KSK: leave RolloverDays at 0 */ }","preventionTips":["Branch on KeyType before setting RolloverDays; only ZSKs accept non-zero.","Use the manual DS-coordinated workflow for KSK rollover, not RolloverDays."],"tags":["dnssec","ksk","rollover","validation"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}