Kea issueshttps://gitlab.isc.org/isc-projects/kea/-/issues2024-03-27T15:26:47Zhttps://gitlab.isc.org/isc-projects/kea/-/issues/3252HA multiple relationships and RADIUS reselect are incompatible2024-03-27T15:26:47ZFrancis DupontHA multiple relationships and RADIUS reselect are incompatibleNothing trivial can be done to fix this other to drop the first query (RADIUS hook parks the query at the subnet select callout and knows the right subnet when the RADIUS response is received). For other queries using cached RADIUS infor...Nothing trivial can be done to fix this other to drop the first query (RADIUS hook parks the query at the subnet select callout and knows the right subnet when the RADIUS response is received). For other queries using cached RADIUS information the correctness relies on the order of the HA and RADIUS hooks (RADIUS before HA).kea2.6.0https://gitlab.isc.org/isc-projects/kea/-/issues/3251Fix drop statistics in subnet6_select and RADIUS hook2024-03-07T14:55:13ZFrancis DupontFix drop statistics in subnet6_select and RADIUS hookThe pkt6-receive-drop is not correctly handled in the subnet6_select callout and the RADIUS hook adds another way to mess it.The pkt6-receive-drop is not correctly handled in the subnet6_select callout and the RADIUS hook adds another way to mess it.next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/3250Unattended terminated state and a reboot2024-03-27T21:53:51ZMarcin SiodelskiUnattended terminated state and a rebootConsider the following case. The clocks on two HA-enabled servers diverge and the clock skew eventually exceeds 60 seconds. As a result, both servers transition to the terminated state. In this state, the servers continue serving DHCP cl...Consider the following case. The clocks on two HA-enabled servers diverge and the clock skew eventually exceeds 60 seconds. As a result, both servers transition to the terminated state. In this state, the servers continue serving DHCP clients but do not exchange the lease updates nor heartbeats. An administrator neglects to correct the clocks and one of the servers reboots. The server enters the `waiting` state and remains in this state hoping that the other server is restarted so they can continue the lease database synchronization and start normal operation. However, the server is unaware that its reboot was not triggered in the course of fixing the clocks, so it will wait for the partner endlessly (or until the administrator comes to work in the morning). The waiting server is not responding to the DHCP traffic until then.
This situation should not occur in a setup where NTP has been enabled. It also should not occur if there is a proper monitoring to detect that the clocks diverge early enough. However, there are chances this situation may happen when all of this is neglected.
The proposed solution is to apply a timeout (could even be several to 10 minutes long) for a server in the waiting state. If the transition of its partner does not occur until this timeout elapses, the server in the waiting state transitions back to the terminated state and continues serving the clients. The waiting server MUST NOT transition to the waiting state immediately after it detects that its partner is in the terminated state to allow enough time to the administrator to reboot the server sequentially after correcting the clocks.
[SF1598](https://isc.lightning.force.com/lightning/r/Case/500S6000003jBs3IAE/view)kea2.5.8https://gitlab.isc.org/isc-projects/kea/-/issues/3247changes in hammer for rocky linux2024-03-28T08:11:54ZMarcin Godzinachanges in hammer for rocky linuxWe need to extend Hammer to build on Rocky Linux 9. We have a business need for this.We need to extend Hammer to build on Rocky Linux 9. We have a business need for this.kea2.5.8Marcin GodzinaMarcin Godzinahttps://gitlab.isc.org/isc-projects/kea/-/issues/3246DHCPRELEASE and lease expiration in active-standby HA setup2024-03-27T12:53:48ZPeter DaviesDHCPRELEASE and lease expiration in active-standby HA setupDHCPvRELEASE lease expiration in active-standby HA setup
Kea 2.5.5
When a client sends a DHCPRELEASE message to a Kea primary HA server, the expired
lease processing settings are honoured.
However, the primary updates the...DHCPvRELEASE lease expiration in active-standby HA setup
Kea 2.5.5
When a client sends a DHCPRELEASE message to a Kea primary HA server, the expired
lease processing settings are honoured.
However, the primary updates the failover server with instructions to delete the
lease.
This leads to a divergence of lease data between the two servers.
[SF00001636](https://isc.lightning.force.com/lightning/r/Case/500S6000004XPRy/view)kea2.5.8https://gitlab.isc.org/isc-projects/kea/-/issues/3244Allow redefine of standard DHCP options2024-03-07T12:07:26ZDarren AnkneyAllow redefine of standard DHCP optionsCurrently, it isn't possible to redefine any standard DHCP option that is defined in Kea. This is a good practice because it prevents administrators from shooting themselves in the foot. However, DHCPv4 is quite old and there have been...Currently, it isn't possible to redefine any standard DHCP option that is defined in Kea. This is a good practice because it prevents administrators from shooting themselves in the foot. However, DHCPv4 is quite old and there have been some newer RFCs that define options that vendors previously could freely use.
An example of this is an older vendor of IP phones who used option 156 with some of their equipment. Option 156 is part of Bulk Lease Query now ([RFC 6926](https://datatracker.ietf.org/doc/html/rfc6926)) since about 2013. This IP phone manufacturer existed from 1998, however. This option was not defined in ISC DHCP, and so could be used there. The option is defined in Kea, though not presently used. Option 156, in the RFC, is defined as containing an integer as a flag of sorts. The old IP phone vendor needs option 156 to contain a string of some kind. This is only an example. This is probably not a one-off situation.
It is unreasonable to require administrators to purchase new equipment as part of the move to Kea, and therefore, it would be better to, in some way, allow the redefine of standard options. This should probably be a deliberate act somehow, perhaps requiring a keyword of some sort, so that the administrator is aware of what they are doing.
[SF1626](https://isc.lightning.force.com/lightning/r/Case/500S6000004IKcWIAW/view)backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/3241Failed to start kea-dhcp if the interface defined in the interface-config lis...2024-03-07T14:54:35ZPranathi NandhigamFailed to start kea-dhcp if the interface defined in the interface-config list is unavailable even though some of the interfaces are upI have observed kea-dhcp failed to start when one of the interface defined in the "interface-config" list does not exist even though other defined interfaces are up and has usable IP address configured. May be dhcp server can be started ...I have observed kea-dhcp failed to start when one of the interface defined in the "interface-config" list does not exist even though other defined interfaces are up and has usable IP address configured. May be dhcp server can be started with the interfaces which are up instead of refusing to start until all interfaces defined in the list comes up.
From code snippet below
void IfacesConfigParser::parseInterfacesList(const CfgIfacePtr& cfg_iface, ConstElementPtr ifaces_list) {
for (auto const& iface : ifaces_list->listValue()) {
std::string iface_name = iface->stringValue();
try {
cfg_iface->use(protocol_, iface_name);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, "Failed to select interface: "
<< ex.what() << " (" << iface->getPosition() << ")");
}
}
}
Here if interface is not found instead of raising an exception, it can be a warning and can be proceeded with other interfaces in the list. I am not sure how feasible it is and its side effect.next-stable-3.0https://gitlab.isc.org/isc-projects/kea/-/issues/3239New Global Counter assigned-addresses2024-03-27T12:53:11ZPeter DaviesNew Global Counter assigned-addressesFeature Request: New Global Counter assigned-addresses
Statistics return per subnet counters "assigned-addresses" and "cumulative-assigned-addresses".
However, globally, only the cumulative-assigned-addresses counter is retu...Feature Request: New Global Counter assigned-addresses
Statistics return per subnet counters "assigned-addresses" and "cumulative-assigned-addresses".
However, globally, only the cumulative-assigned-addresses counter is returned.
It may interest administrators to know the total number of assigned addresses per
server.
[SF00001629](https://isc.lightning.force.com/lightning/r/Case/500S6000004QXmC/view)kea2.5.8https://gitlab.isc.org/isc-projects/kea/-/issues/3232Include JSONs from doc/examples in the ARM2024-02-01T14:54:13ZAndrei Pavelandrei@isc.orgInclude JSONs from doc/examples in the ARMThe configurations in `doc/examples` are mainly aimed at helping administrators, yet they are not included in the ARM with the exception of a few complex HA examples.
Some of the configurations are mentioned through path without linking...The configurations in `doc/examples` are mainly aimed at helping administrators, yet they are not included in the ARM with the exception of a few complex HA examples.
Some of the configurations are mentioned through path without linking anywhere. Furthermore, the path matches the location in the Kea sources, but not in the Kea installation. An administrator would have to git-clone to find them.
I suggest adding a section to the ARM which includes all of them. This would be done programmatically as opposed to hardcoding each file. Ideally, the directory hierarchy would also be respected and displayed in the ARM section.next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/3228Add monitoring instrumentation around `dhcp-disable` state.2024-02-01T14:49:57ZTomek MrugalskiAdd monitoring instrumentation around `dhcp-disable` state.For details, see [github PR#133](https://github.com/isc-projects/kea/pull/133).For details, see [github PR#133](https://github.com/isc-projects/kea/pull/133).next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/3226HA lease updates do not create an accounting entry in v62024-01-25T15:00:10ZAndrei Pavelandrei@isc.orgHA lease updates do not create an accounting entry in v6In v6, HA lease updates are done with the `lease6-bulk-apply` command which is not handled in the `command_processed` RADIUS callout.
This is unlike v4 which does create accounting entries for HA lease updates sent via `lease4-update`.In v6, HA lease updates are done with the `lease6-bulk-apply` command which is not handled in the `command_processed` RADIUS callout.
This is unlike v4 which does create accounting entries for HA lease updates sent via `lease4-update`.next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/3225when applying MT settings from CB the libs compatibility is not rechecked2024-03-27T13:50:40ZRazvan Becheriuwhen applying MT settings from CB the libs compatibility is not recheckedMT disabled -\> check libs (success) -\> load libs -\> CB load config -\> MT enabled -\> no checking of libs -\> could end up with non MT compatible libs loaded and used in MTMT disabled -\> check libs (success) -\> load libs -\> CB load config -\> MT enabled -\> no checking of libs -\> could end up with non MT compatible libs loaded and used in MTnext-stable-3.0https://gitlab.isc.org/isc-projects/kea/-/issues/3224CB commands should use processDhcp[4|6]Config to validate content of global p...2024-02-01T14:46:08ZRazvan BecheriuCB commands should use processDhcp[4|6]Config to validate content of global parameterssetting global parameters using CB commands does not check if values are valid. They are merged into the current config with no check. this could have an undesired effect on the running server.
global scalar parameters v4:
```plaintext...setting global parameters using CB commands does not check if values are valid. They are merged into the current config with no check. this could have an undesired effect on the running server.
global scalar parameters v4:
```plaintext
if ( (config_pair.first == "renew-timer") ||
(config_pair.first == "rebind-timer") ||
(config_pair.first == "valid-lifetime") ||
(config_pair.first == "min-valid-lifetime") ||
(config_pair.first == "max-valid-lifetime") ||
(config_pair.first == "decline-probation-period") ||
(config_pair.first == "dhcp4o6-port") ||
(config_pair.first == "echo-client-id") ||
(config_pair.first == "match-client-id") ||
(config_pair.first == "authoritative") ||
(config_pair.first == "next-server") ||
(config_pair.first == "server-hostname") ||
(config_pair.first == "boot-file-name") ||
(config_pair.first == "server-tag") ||
(config_pair.first == "reservation-mode") ||
(config_pair.first == "reservations-global") ||
(config_pair.first == "reservations-in-subnet") ||
(config_pair.first == "reservations-out-of-pool") ||
(config_pair.first == "calculate-tee-times") ||
(config_pair.first == "t1-percent") ||
(config_pair.first == "t2-percent") ||
(config_pair.first == "cache-threshold") ||
(config_pair.first == "cache-max-age") ||
(config_pair.first == "hostname-char-set") ||
(config_pair.first == "hostname-char-replacement") ||
(config_pair.first == "ddns-send-updates") ||
(config_pair.first == "ddns-override-no-update") ||
(config_pair.first == "ddns-override-client-update") ||
(config_pair.first == "ddns-replace-client-name") ||
(config_pair.first == "ddns-generated-prefix") ||
(config_pair.first == "ddns-qualifying-suffix") ||
(config_pair.first == "ddns-update-on-renew") ||
(config_pair.first == "ddns-use-conflict-resolution") ||
(config_pair.first == "ddns-conflict-resolution-mode") ||
(config_pair.first == "ddns-ttl-percent") ||
(config_pair.first == "store-extended-info") ||
(config_pair.first == "statistic-default-sample-count") ||
(config_pair.first == "statistic-default-sample-age") ||
(config_pair.first == "early-global-reservations-lookup") ||
(config_pair.first == "ip-reservations-unique") ||
(config_pair.first == "reservations-lookup-first") ||
(config_pair.first == "parked-packet-limit") ||
(config_pair.first == "allocator") ||
(config_pair.first == "offer-lifetime") ) {
CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
config_pair.second);
continue;
}
```
global scalar parameters v6:
```plaintext
if ( (config_pair.first == "renew-timer") ||
(config_pair.first == "rebind-timer") ||
(config_pair.first == "preferred-lifetime") ||
(config_pair.first == "min-preferred-lifetime") ||
(config_pair.first == "max-preferred-lifetime") ||
(config_pair.first == "valid-lifetime") ||
(config_pair.first == "min-valid-lifetime") ||
(config_pair.first == "max-valid-lifetime") ||
(config_pair.first == "decline-probation-period") ||
(config_pair.first == "dhcp4o6-port") ||
(config_pair.first == "server-tag") ||
(config_pair.first == "reservation-mode") ||
(config_pair.first == "reservations-global") ||
(config_pair.first == "reservations-in-subnet") ||
(config_pair.first == "reservations-out-of-pool") ||
(config_pair.first == "calculate-tee-times") ||
(config_pair.first == "t1-percent") ||
(config_pair.first == "t2-percent") ||
(config_pair.first == "cache-threshold") ||
(config_pair.first == "cache-max-age") ||
(config_pair.first == "hostname-char-set") ||
(config_pair.first == "hostname-char-replacement") ||
(config_pair.first == "ddns-send-updates") ||
(config_pair.first == "ddns-override-no-update") ||
(config_pair.first == "ddns-override-client-update") ||
(config_pair.first == "ddns-replace-client-name") ||
(config_pair.first == "ddns-generated-prefix") ||
(config_pair.first == "ddns-qualifying-suffix") ||
(config_pair.first == "ddns-update-on-renew") ||
(config_pair.first == "ddns-use-conflict-resolution") ||
(config_pair.first == "ddns-conflict-resolution-mode") ||
(config_pair.first == "ddns-ttl-percent") ||
(config_pair.first == "store-extended-info") ||
(config_pair.first == "statistic-default-sample-count") ||
(config_pair.first == "statistic-default-sample-age") ||
(config_pair.first == "early-global-reservations-lookup") ||
(config_pair.first == "ip-reservations-unique") ||
(config_pair.first == "reservations-lookup-first") ||
(config_pair.first == "parked-packet-limit") ||
(config_pair.first == "allocator") ||
(config_pair.first == "pd-allocator") ) {
CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
config_pair.second);
continue;
}
```
lists might not be complete. need to check.
only few parameters are checked - one is valid-lifetime:
```plaintext
void
sanityChecks(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
/// Global lifetime sanity checks
cfg->sanityChecksLifetime("valid-lifetime");
/// Shared network sanity checks
const SharedNetwork4Collection* networks = cfg->getCfgSharedNetworks4()->getAll();
if (networks) {
sharedNetworksSanityChecks(*networks, global->get("shared-networks"));
}
}
```
some are not checked even by processDhcp\[4|6\]Config:
```plaintext
if (allow_packet_park) {
// Get the parking limit. Parsing should ensure the value is present.
uint32_t parked_packet_limit = 0;
data::ConstElementPtr ppl = CfgMgr::instance().getCurrentCfg()->
getConfiguredGlobal(CfgGlobals::PARKED_PACKET_LIMIT);
if (ppl) {
parked_packet_limit = ppl->intValue();
}
if (parked_packet_limit) {
auto const& parking_lot =
ServerHooks::getServerHooks().getParkingLotPtr(hook_label);
if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
// We can't park it so we're going to throw it on the floor.
LOG_DEBUG(packet4_logger, DBGLVL_PKT_HANDLING, parking_lot_full_msg)
.arg(parked_packet_limit)
.arg(query->getLabel());
isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
static_cast<int64_t>(1));
rsp.reset();
return;
}
}
```backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/3223kea v4 returns status-get 0 when not connected to database2024-02-21T09:17:05ZMarcin Godzinakea v4 returns status-get 0 when not connected to databaseDuring the missing lease database connection process, we send 'status-'get' to Kea.
Kea v6 returns:
```
{
"result": 1,
"text": "Error during command processing: no current lease manager is available"
}
```
Kea v4 returns norm...During the missing lease database connection process, we send 'status-'get' to Kea.
Kea v6 returns:
```
{
"result": 1,
"text": "Error during command processing: no current lease manager is available"
}
```
Kea v4 returns normal status:
```
{
"arguments": {
"multi-threading-enabled": true,
(...)
"uptime": 4
},
"result": 0
}
```
Getting result 0 on kea4 is misleading when there is no database connection.
**These features should be included in tests `tests/dhcp/test_database.py::test_db_retry*`. Please inform QA about the merging solution for this issue.**next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/3221Minor doc update: server limitations update after ping-check2024-03-20T11:29:29ZTomek MrugalskiMinor doc update: server limitations update after ping-checkThe section 8.12 (DHCPv4 server limitations) still claims this:
> _The DHCPv4 server does not verify that an assigned address is unused. According to RFC 2131, the allocating server should verify that an address is not used by sending a...The section 8.12 (DHCPv4 server limitations) still claims this:
> _The DHCPv4 server does not verify that an assigned address is unused. According to RFC 2131, the allocating server should verify that an address is not used by sending an ICMP echo request._
This is no longer true after ping-check was implemented.kea2.6.0https://gitlab.isc.org/isc-projects/kea/-/issues/3220Debian apt repository setup installs `apt-transport-https` dummy package2024-03-14T14:31:13ZDirk HeinrichsDebian apt repository setup installs `apt-transport-https` dummy packagePlease stop installing that package. It's a dummy since Debian Buster/Ubuntu 18.04.Please stop installing that package. It's a dummy since Debian Buster/Ubuntu 18.04.outstandingTomek MrugalskiTomek Mrugalskihttps://gitlab.isc.org/isc-projects/kea/-/issues/3219Implement RFC9527: Homenet DHCPv6 options2024-01-25T14:54:51ZTomek MrugalskiImplement RFC9527: Homenet DHCPv6 optionsA new set of three DHCPv6 options are being published in [RFC9527](https://www.rfc-editor.org/authors/rfc9527.html). If this link no longer works, it means the RFC is published.
The options' formats are reasonably simple (a 16-bits long...A new set of three DHCPv6 options are being published in [RFC9527](https://www.rfc-editor.org/authors/rfc9527.html). If this link no longer works, it means the RFC is published.
The options' formats are reasonably simple (a 16-bits long bit field + fqdn) and are DHCPv6 only. There's no special processing - normal ORO stuff, although the server will likely keep some values user specific (so will be used mainly as host reservation options).backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/3218Kea dhcp v4 server ip reservation configuration using uuid-guid (dhcp option ...2024-03-26T13:17:34ZBenoit SansoniKea dhcp v4 server ip reservation configuration using uuid-guid (dhcp option 97; rfc 4578)Hi,
I would like to set a dhcp v4 reservation ip using "uuid-guid" (that correspond to dhcp option 97 / RFC 4578).
This is my current kea server configuration using an hardware address that works fine :
"reservations": [...Hi,
I would like to set a dhcp v4 reservation ip using "uuid-guid" (that correspond to dhcp option 97 / RFC 4578).
This is my current kea server configuration using an hardware address that works fine :
"reservations": [
{
"hostname": "board",
"hw-address": "01:02:03:04:05:06",
"ip-address": "192.168.0.2",
"option-data": [
{
"name": "boot-file-name",
"data": "file.bin"
}
]
},
When I replaced in this configuration the hw-address by "uuid-guid", the "uuid-guid" filed is not expected by kea dhcp server.
In the documentation I can see that the default host reservation identifiers are:
"host-reservation-identifiers": [ "circuit-id", "hw-address", "duid", "client-id" ]
Is the "uuid-guid" is supported for IP reservation ?
Is it a feature that will be developped in the future ?
If the reservation with "uuid-guid" identifier is supported, What should configuration need to be applied ?
Thanks in advance for your help
Benoitoutstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/3217Neighbor discovery for dhcpv62024-02-19T21:40:42ZVaclav MichalekNeighbor discovery for dhcpv6This is a request to implement IPv6 neighbor discovery mechanism (rfc4861) in DHCPv6 server to obtain MAC hardware addresses.
The method is also suggested in [related issue](https://gitlab.isc.org/isc-projects/kea/-/issues/1729 "Feature...This is a request to implement IPv6 neighbor discovery mechanism (rfc4861) in DHCPv6 server to obtain MAC hardware addresses.
The method is also suggested in [related issue](https://gitlab.isc.org/isc-projects/kea/-/issues/1729 "Feature request: DHCPv6 - use real MAC address from dhcp6 request (mac-sources=raw)").
**Is your feature request related to a problem? Please describe.**
The feature is needed for reliable host-based reservations and identification of DHCPv6 clients.
**Describe the solution you'd like**
Two new mac-source methods (query OS neighbor cache, neighbor discovery) are to be implemented.
```plaintext
"mac-sources": [ "neigh-cache", "neigh-discovery" ]
```
**Describe alternatives you've considered** At this time, there is no practical alternative.
**Funding its development** No funding.
**Participating in development** I am planning to write the code (though with no experience with Kea developement).
**Contacting you** ... E-mail in my profile.backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/3216Setting YANG list elements with singlequotes in key values is not possible in...2024-01-18T14:58:00ZAndrei Pavelandrei@isc.orgSetting YANG list elements with singlequotes in key values is not possible in our unit testing frameworkOur internal NETCONF test framework in the form of `YangRepr`, particularly the `YangRepr::set` functionality does not support setting list elements that have singlequotes in the value of a key. This is because setting a node is done by ...Our internal NETCONF test framework in the form of `YangRepr`, particularly the `YangRepr::set` functionality does not support setting list elements that have singlequotes in the value of a key. This is because setting a node is done by providing the xpath as a plain string and singlequotes are used to delimit the value of the key, so upon finding a singlequote in the value, the libyang parser thinks the value ends sooner than it actually does and does not know what to do with the rest of the xpath.
This is not a problem in production code, because production code has no need for setting YANG nodes, but instead is only concerned with retrieving them from the sysrepo datastore.
The issue may become more prevalent if issue 3198 gets merged as it was written at the time this issue was created. It makes `data` a key which is more likely to contain a singlequote than other keys, which is also why this issue became obvious there. The issue occurred in unit tests.
```
[ RUN ] ConfigTestKeaV4.examples4
libyang[0]: Invalid character 0x73 ('s'), perhaps "'Error: here'" is supposed to be a function call.
config_unittests.cc:332: Failure
Failed
json = loadFile(path) threw type: N3isc4yang12NetconfErrorE, what: setting item 'nullopt' at '/kea-dhcp4-server:config/option-data[code='56'][space='dhcp4'][data='Error: here's a DHCPNAK!']': Session::setItem: Couldn't set '/kea-dhcp4-server:config/option-data[code='56'][space='dhcp4'][data='Error: here's a DHCPNAK!']': SR_ERR_INVAL_ARG
Google Test trace:
config_unittests.cc:330:
* Tested file: /home/andrei/work/isc/kea-3198-vivso-suboptions-not-properly-supported-in-netconf/doc/examples/kea4/all-options.json
[ FAILED ] ConfigTestKeaV4.examples4 (509 ms)
```
This change was done to avoid it:
```diff
diff --git a/doc/examples/kea4/all-options.json b/doc/examples/kea4/all-options.json
index 5e7d7ccbc7..f52105691b 100644
--- a/doc/examples/kea4/all-options.json
+++ b/doc/examples/kea4/all-options.json
@@ -691,3 +691,3 @@
"code": 56,
- "data": "Error: here's a DHCPNAK!",
+ "data": "Error: here is a DHCPNAK!",
"name": "dhcp-message"
```
One may think of encoding the singlequote as Kea does with the commas in user-context under the lease CSV files. That is not ideal, if even possible, since the singlequote would need to be decoded in get unctionality which means it has an effect on production code, but moreover it might not be compatible with setting outside `YangRepr`, via e.g. sysrepocfg.outstanding