[Kea-users] NAK responses getting dropped

Elton, Norman N wnelto at wm.edu
Tue Oct 13 15:07:52 UTC 2026


>> The broadcast behavior and broadcast bit behavior for client, server
>> and relay are described here: https://www.rfc-editor.org/info/rfc2131/#section-4.1

Thanks, we’re continuing our research here. The RFC does state:

If 'giaddr' is set in the DHCPREQUEST message, the client is on a
different subnet.  The server MUST set the broadcast bit in the
DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
client, because the client may not have a correct network address
or subnet mask, and the client may not be answering ARP requests.

I’ve mocked this up in a lab environment (running Kea in docker). With packet debug logging turned up to 99, I see:

2026-10-13 13:50:58.468 DEBUG [kea-dhcp4.packets/8.140737458109240] DHCP4_RESPONSE_DATA [hwtype=1 02:00:00:12:34:56], cid=[no info], tid=0x12345678: responding with packet DHCPNAK (type 6), packet details: local_address=172.21.0.2:67, remote_address=100.70.0.1:67,
msg_type=DHCPNAK (6), trans_id=0x12345678,
options:
  type=053, len=001: 6 (uint8)
  type=054, len=004: 172.21.0.2

The same packet captured in tcpdump (running on the server - in the docker container):

IP (tos 0x0, ttl 64, id 19991, offset 0, flags [DF], proto UDP (17), length 278)
    172.21.0.2.67 > 100.70.0.1.67: [bad udp cksum 0x1172 -> 0xd2df!] BOOTP/DHCP, Reply, length 250, hops 1, xid 0x12345678, Flags [none] (0x0000)
          Gateway-IP 100.70.0.1
          Client-Ethernet-Address 02:00:00:12:34:56
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message (53), length 1: NACK
            Server-ID (54), length 4: 172.21.0.2
            END (255), length 0

The flags are set to 0x0000, indicating a unicast reply. This seems contrary to the RFC stipulation that NAKs are always sent with the broadcast bit set. Could this be a misbehavior on the Kea server?

I verified the same behavior on Kea 3.1.7. Working on verifying it on newer releases.

Norman




From: Elton, Norman N <wnelto at wm.edu>
Date: Friday, October 9, 2026 at 8:31 AM
To: Kea user's list <kea-users at lists.isc.org>
Subject: Re: NAK responses getting dropped

>> It could be that Kea isn't sending the packet
>> perhaps, but that seems the least likely scenario so far.

You were right to be suspicious.  A second packet capture shows the NAKs leaving the server. Not entirely sure why I didn’t spot them before. Apologies, and thanks for the thoughtful reply!!

A little more research has uncovered a new wrinkle. These clients are sending a L2 broadcast packet, requesting their now-invalid IP address. That is being forwarded along by our router (Juniper MX). The response appears to make it to the router, but gets dropped … under one condition. The dropped requests have the “unicast” flag set, even though they’re clearly a broadcast packet. We need to dig into the RFCs to see if that’s an acceptable behavior. The response has the same flag set, and so the router is presumably refusing to re-broadcast the response. We’ve verified this behavior by crafting specific DHCP requests with scapy.

We’ll update this thread when we find more.

Norman



From: Kea-users <kea-users-bounces at lists.isc.org> on behalf of Elton, Norman N <wnelto at wm.edu>
Date: Wednesday, October 7, 2026 at 8:49 AM
To: Kea user's list <kea-users at lists.isc.org>
Subject: Re: [Kea-users] NAK responses getting dropped


Good morning!

I’m running the packet capture on the server itself. Not entirely sure what you mean by “full logs”. I cranked the level up to DEBUG for all loggers and did not see any additional messages related to these transactions. Happy to do more digging.

I’ll paste a trimmed-down version of our configuration below. I removed all the unrelated subnets.

Thanks!!

Norman


{
  "Dhcp4": {
    "valid-lifetime": 86400,
    "interfaces-config": {
      "interfaces": [
        "*"
      ],
      "dhcp-socket-type": "udp"
    },
    "decline-probation-period": 3600,
    "lease-database": {
      "type": "memfile",
      "persist": true,
      "lfc-interval": 86400,
      "name": "/var/lib/kea/kea-leases4.csv"
    },
    "hosts-database": {
      "type": "mysql",
      "name": "kea",
      "user": "kea",
      "password": "..."
    },
    "shared-networks": [
      ...
    ],
    "subnet4": [
      {
        "user-context": {
          "name": "STUDENT-TUCKER",
          "regions": "student"
        },
        "subnet": "100.70.0.0/16",
        "valid-lifetime": 86400,
        "pools": [
          {
            "pool": "100.70.0.50 - 100.70.99.255",
            "client-class": "HA_KEA_01"
          },
          {
            "pool": "100.70.100.0 - 100.70.199.255",
            "client-class": "HA_KEA_02"
          },
          {
            "pool": "100.70.235.0 - 100.70.244.255",
            "client-class": "HA_KEA_01"
          },
          {
            "pool": "100.70.245.0 - 100.70.254.255",
            "client-class": "HA_KEA_02"
          }
        ],
        "option-data": [
          {
            "name": "routers",
            "data": "100.70.0.1"
          }
        ],
        "id": 1682309120
      }
    ],
    "echo-client-id": false,
    "sanity-checks": {
      "lease-checks": "fix"
    },
    "client-classes": [
      {
        "name": "INOVA_CLOCK",
        "test": "hexstring(substring(pkt4.mac, 0, 3), ':') == '00:60:35'",
        "option-data": [
          {
            "name": "CLOCK-INFO",
            "data": "timeserver=time.example.org;timezone=-5;dst=-1 8 2 2 1 1 10 2"
          }
        ]
      },
      {
        "name": "JUNIPER",
        "test": "substring(option[60].text, 0, 7) == 'Juniper'",
        "option-data": [
          {
            "name": "EZ_PROVISIONING_CONFIG_FILE_NAME",
            "space": "EZ_PROVISIONING_SPACE",
            "data": "..."
          },
          {
            "name": "EZ_PROVISIONING_IMAGE_TRANSFER_MODE",
            "space": "EZ_PROVISIONING_SPACE",
            "data": "http"
          },
          {
            "name": "vendor-encapsulated-options",
            "always-send": true
          }
        ]
      },
      {
        "name": "AUDIOCODES_405",
        "test": "option[60].hex == '405HD' or option[77].hex == '405HD'",
        "option-data": [
          {
            "name": "AUDIOCODES-PROVISIONING",
            "data": "...",
            "always-send": true
          }
        ]
      }
    ],
    "option-def": [
      {
        "name": "CLOCK-INFO",
        "code": 230,
        "type": "string"
      },
      {
        "name": "AUDIOCODES-PROVISIONING",
        "code": 160,
        "type": "string"
      },
      {
        "name": "EZ_PROVISIONING",
        "type": "empty",
        "code": 43,
        "encapsulate": "EZ_PROVISIONING_SPACE"
      },
      {
        "name": "EZ_PROVISIONING_CONFIG_FILE_NAME",
        "code": 1,
        "space": "EZ_PROVISIONING_SPACE",
        "type": "string"
      },
      {
        "name": "EZ_PROVISIONING_IMAGE_TRANSFER_MODE",
        "code": 3,
        "space": "EZ_PROVISIONING_SPACE",
        "type": "string"
      },
      {
        "name": "EZ_PROVISIONING_SERVER",
        "code": 150,
        "type": "ipv4-address"
      }
    ],
    "option-data": [
      {
        "name": "domain-name-servers",
        "data": "192.168.29.9, 192.168.20.9",
        "always-send": true
      },
      {
        "name": "domain-name",
        "data": "example.org"
      }
    ],
    "match-client-id": false,
    "host-reservation-identifiers": [
      "hw-address"
    ],
    "reservations-global": false,
    "reservations-in-subnet": false,
    "reservations-out-of-pool": true,
    "authoritative": true,
    "loggers": [
      {
        "name": "kea-dhcp4",
        "output_options": [
          {
            "output": "syslog",
            "flush": false
          }
        ],
        "severity": "INFO"
      }
    ],
    "multi-threading": {
      "enable-multi-threading": true,
      "thread-pool-size": 4,
      "packet-queue-size": 28
    },
    "control-socket": {
      "socket-type": "unix",
      "socket-name": "/var/run/kea/control-socket"
    },
    "hooks-libraries": [
      {
        "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_mysql_cb.so",
        "parameters": {}
      },
      {
        "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_lease_cmds.so",
        "parameters": {}
      },
      {
        "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_stat_cmds.so",
        "parameters": {}
      },
      {
        "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_ha.so",
        "parameters": {
          "high-availability": [
            {
              "this-server-name": "KEA_01",
              "mode": "load-balancing",
              "heartbeat-delay": 10000,
              "max-response-delay": 60000,
              "max-ack-delay": 5000,
              "max-unacked-clients": 5,
              "max-rejected-lease-updates": 10,
              "delayed-updates-limit": 100,
              "peers": [
                {
                  "name": "KEA_01",
                  "url": "http://192.168.10.154:3000",
                  "role": "primary",
                  "auto-failover": true
                },
                {
                  "name": "KEA_02",
                  "url": "http://192.168.10.155:3000",
                  "role": "secondary",
                  "auto-failover": true
                }
              ]
            }
          ]
        }
      }
    ]
  }
}




>> HI Norman,

>> Where are you capturing the packets?  Directly on the Kea server or
>> somewhere else?  Also, full logs and your Kea configuration would be
>> necessary to get a clearer picture of what might be happening.

>> Thank you,
>> Darren Ankney

From: Elton, Norman N <wnelto at wm.edu>
Date: Friday, October 2, 2026 at 10:52 AM
To: Kea user's list <kea-users at lists.isc.org>
Subject: NAK responses getting dropped

We have clients requesting addresses in the wrong subnet, which Kea is trying to send a NAK:

[kea-dhcp4.dhcp4.123] DHCP4_QUERY_LABEL received query: [hwtype=1 bc:9f:58:1b:cf:f3], cid=[01:bc:9f:58:1b:cf:f3], tid=0x6a744f8
[kea-dhcp4.packets.123] DHCP4_PACKET_RECEIVED [hwtype=1 bc:9f:58:1b:cf:f3], cid=[01:bc:9f:58:1b:cf:f3], tid=0x6a744f8: DHCPREQUEST (type 3) received from 100.70.0.2 to 128.239.10.154 on interface bond0.10
[kea-dhcp4.leases.123] DHCP4_INIT_REBOOT [hwtype=1 bc:9f:58:1b:cf:f3], cid=[01:bc:9f:58:1b:cf:f3], tid=0x6a744f8: client is in INIT-REBOOT state and requests address 100.69.0.173
[kea-dhcp4.packets.123] DHCP4_PACKET_SEND [hwtype=1 bc:9f:58:1b:cf:f3], cid=[no info], tid=0x6a744f8: trying to send packet DHCPNAK (type 6) from 128.239.10.154:67 to 100.70.0.2:67 on interface bond0.10

Problem is, the NAK is not being sent. When running packet captures, I see tons ACKs but no NAKs. The pkt4-nak-sent statistic is increasing. Just … no packets on the wire.

I cranked up kea-dhcp4.packets to DEBUG mode, no additional information.

Kea 2.6.4 running in load-balancing high availability mode.

Any suggestions?

Thanks,

Norman Elton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/kea-users/attachments/20261013/3a21e655/attachment-0001.htm>


More information about the Kea-users mailing list