{"record":{"id":"4d3fae0a7c8f2749","repo":"TechnitiumSoftware/DnsServer","slug":"dns-server-does-not-have-tsig-key-tsigauthentica","errorCode":null,"errorMessage":"DNS Server does not have TSIG key '{tsigAuthenticatedKeyName}' configured to authenticate dynamic updates for {zoneInfo.TypeName} zone: {zoneInfo.DisplayName}","messagePattern":"DNS Server does not have TSIG key '(.+?)' configured to authenticate dynamic updates for (.+?) zone: (.+?)","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/DnsServer.cs","lineNumber":3550,"sourceCode":"                                    List<NameServerAddress> updatedNameServers = new List<NameServerAddress>(primaryNameServerAddresses.Count);\n\n                                    foreach (NameServerAddress primaryNameServer in primaryNameServerAddresses)\n                                    {\n                                        if (primaryNameServer.Protocol == DnsTransportProtocol.Tcp)\n                                            updatedNameServers.Add(primaryNameServer);\n                                        else\n                                            updatedNameServers.Add(primaryNameServer.Clone(DnsTransportProtocol.Tcp));\n                                    }\n\n                                    primaryNameServerAddresses = updatedNameServers;\n                                }\n                                break;\n                        }\n\n                        TsigKey key = null;\n\n                        if (!string.IsNullOrEmpty(tsigAuthenticatedKeyName) && ((_tsigKeys is null) || !_tsigKeys.TryGetValue(tsigAuthenticatedKeyName, out key)))\n                            throw new DnsServerException(\"DNS Server does not have TSIG key '\" + tsigAuthenticatedKeyName + \"' configured to authenticate dynamic updates for \" + zoneInfo.TypeName + \" zone: \" + zoneInfo.DisplayName);\n\n                        DnsClient dnsClient = new DnsClient(primaryNameServerAddresses);\n\n                        dnsClient.Proxy = _proxy;\n                        dnsClient.IPv6Mode = _ipv6Mode;\n                        dnsClient.Retries = _forwarderRetries;\n                        dnsClient.Timeout = _forwarderTimeout;\n                        dnsClient.Concurrency = 1;\n\n                        DnsDatagram newRequest = request.Clone();\n                        newRequest.SetRandomIdentifier();\n\n                        DnsDatagram newResponse;\n\n                        if (key is null)\n                            newResponse = await dnsClient.RawResolveAsync(newRequest);\n                        else\n                            newResponse = await dnsClient.TsigResolveAsync(newRequest, key);","sourceCodeStart":3532,"sourceCodeEnd":3568,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/DnsServer.cs#L3532-L3568","documentation":"Thrown during zone secondary/zone transfer handling when tsigAuthenticatedKeyName is non-empty but no matching key exists in _tsigKeys (or _tsigKeys itself is null). TSIG (RFC 2845) signs dynamic updates and zone transfers; the server cannot authenticate to the primary without the configured key.","triggerScenarios":"Configuring a secondary zone with TSIG-authenticated updates/transfers and referencing a key name not present in the TSIG key store; deleting a TSIG key without updating zones that reference it; case mismatch of the key name.","commonSituations":"Key name typo in zone config; key was renamed/deleted from Settings > TSIG Keys; copying zone config between servers without copying the TSIG keys; case sensitivity difference (BIND vs Technitium key-name casing).","solutions":["Create a TSIG key with the exact name in Settings > TSIG Keys (or via the API) and update both peers to use it.","Match the key name case-sensitively between primary and secondary servers.","If TSIG is not actually needed, clear tsigAuthenticatedKeyName on the zone.","Re-sync the TSIG key (algorithm + secret) between both servers; both ends must share the identical key material."],"exampleFix":"// before\nzone.TsigKeyName = \"transfer-key\";   // no such key configured\n\n// after\nserver.TsigKeys.Add(new TsigKey(\"transfer-key\", TsigAlgorithm.HmacSha256, secret));\nzone.TsigKeyName = \"transfer-key\";","handlingStrategy":"validation","validationCode":"void EnsureTsigKey(ITsigKeyStore keys, string? name)\n{\n    if (!string.IsNullOrEmpty(name) && (keys is null || !keys.Contains(name)))\n        throw new ConfigurationException($\"TSIG key '{name}' is not configured\");\n}","typeGuard":"static bool TsigKeyExists(ITsigKeyStore keys, string? name)\n    => string.IsNullOrEmpty(name) || (keys is not null && keys.Contains(name));","tryCatchPattern":"try { await server.DoZoneTransferAsync(zone); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"does not have TSIG key\")) { log.Error(\"Create/rename the TSIG key referenced by the zone\"); }","preventionTips":["Keep the TSIG key store and zone references in sync.","Match key-name casing between primary and secondary.","Audit zones when deleting a TSIG key."],"tags":["tsig","zone-transfer","auth","secondary-zone"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}