{"record":{"id":"f5a15d4f9554730a","repo":"TechnitiumSoftware/DnsServer","slug":"nsec3-iterations-valid-range-is-0-50","errorCode":null,"errorMessage":"NSEC3 iterations valid range is 0-50","messagePattern":"NSEC3 iterations valid range is 0-50","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":483,"sourceCode":"                else\n                {\n                    salt = [];\n                }\n            }\n\n            SignZone([kskPrivateKey, zskPrivateKey], dnsKeyTtl, useNSec3, iterations, salt);\n        }\n\n        public void SignZone(IReadOnlyCollection<DnssecPrivateKey> dnssecPrivateKeys, uint dnsKeyTtl, bool useNSec3, ushort iterations = 0, byte[] salt = null)\n        {\n            //do validations\n            if (_dnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"Cannot sign zone: the zone is already signed.\");\n\n            if (useNSec3)\n            {\n                if (iterations > 50)\n                    throw new ArgumentOutOfRangeException(nameof(iterations), \"NSEC3 iterations valid range is 0-50\");\n\n                if (salt.Length > 32)\n                    throw new ArgumentOutOfRangeException(nameof(salt), \"NSEC3 salt length valid range is 0-32\");\n            }\n\n            bool foundKsk = false;\n            bool foundZsk = false;\n\n            foreach (DnssecPrivateKey dnssecPrivateKey in dnssecPrivateKeys)\n            {\n                switch (dnssecPrivateKey.KeyType)\n                {\n                    case DnssecPrivateKeyType.KeySigningKey:\n                        foundKsk = true;\n                        break;\n\n                    case DnssecPrivateKeyType.ZoneSigningKey:\n                        foundZsk = true;","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L465-L501","documentation":"Thrown by the collection overload PrimaryZone.SignZone when useNSec3 is true and iterations > 50. NSEC3 hash iterations above 50 are rejected (RFC 5151 operational guidance + DoS-amplification concerns) via ArgumentOutOfRangeException(nameof(iterations)) before key validation.","triggerScenarios":"zone.SignZone(keys, ttl, useNSec3: true, iterations: 100).","commonSituations":"Copying an iterations count from a security-hardening guide for a different algorithm; legacy zones migrated with high iterations.","solutions":["Pass iterations in 0-50; 0 or 1 is the modern recommendation.","Prefer NSEC over NSEC3 with high iterations if denial-of-existence is the only concern.","Clamp the requested value to the valid range before calling."],"exampleFix":"// before\nzone.SignZone(keys, ttl, useNSec3: true, iterations: 100);\n\n// after\nushort iterations = (ushort)Math.Clamp(requestedIterations, 0, 50);\nzone.SignZone(keys, ttl, useNSec3: true, iterations: iterations);","handlingStrategy":"validation","validationCode":"if (iterations > 50) throw new ArgumentOutOfRangeException(nameof(iterations));\nzone.SignZone(keys, ttl, useNSec3: true, iterations, salt);","typeGuard":"static bool IsValidNsec3Iterations(int n) => n >= 0 && n <= 50;","tryCatchPattern":null,"preventionTips":["Use 0-1 NSEC3 iterations (modern guidance).","Clamp iterations to 0-50 before signing.","Prefer NSEC over high-iteration NSEC3."],"tags":["csharp","dns","dnssec","nsec3","validation","technitium-dns"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}