# Release 2026.05.12-a6845223

## Breaking Changes

## Other Changes and Enhancements

 * New [kumo.counter_series](../reference/kumo.counter_series/index.md)
   module exposing in-memory rolling counters backed by a fixed-size ring of
   time buckets. Useful for short-term, per-process bookkeeping of event
   rates from policy. Thanks to @kayozaki!
 * New [message:import_headers](../reference/message/import_headers.md) method,
   a more flexible alternative to `message:import_x_headers`. Supports exact
   names and trailing-`*` wildcards, first/last/all match modes, optional
   removal of matched headers, and configurable name-transform styles
   (snake/kebab/camel/pascal case).
 * New `accept_invalid_certs` option on
   [kumo.http.build_client](../reference/kumo.http/build_client.md) that
   disables TLS certificate verification for the resulting client. Intended
   for development and testing against self-signed endpoints; see the
   reference for the security caveats. Thanks to @Fallmay! #504
 * The HTTP injection API now supports per-recipient metadata via a new
   `metadata` field on each recipient object. Key-value pairs supplied
   there are stored on the resulting message under the `extra` metadata
   key, accessible from Lua hooks via `msg:get_meta('extra')`.
 * Documented a naming convention for user-defined message and connection
   meta keys: prefix application-specific keys with `x_` to avoid
   collisions with current and future KumoMTA-predefined meta names. This
   aligns with the `x_*` keys produced by
   [message:import_x_headers](../reference/message/import_x_headers.md) and
   the default `snake_case` transform used by
   [message:import_headers](../reference/message/import_headers.md);
   KumoMTA's own predefined meta keys will never start with `x_`. See the
   [naming convention](../reference/message/set_meta.md#naming-convention-for-user-defined-keys)
   for details. Existing meta names continue to work; the `x_` prefix is a
   recommendation, not a hard requirement.

## Fixes

 * proxy-server: TCP keepalive is now configured on inbound and outbound
   sockets handled by the proxy listener, so unresponsive peers are detected
   and the connection is closed rather than left open indefinitely.  The
   probe timing can be tuned (or keepalive disabled) via the new
   [tcp_keepalive](../reference/proxy/start_proxy_listener/tcp_keepalive.md)
   field on `proxy.start_proxy_listener`.  Thanks to @jack-atlas! #509
 * A message with multipart/mixed as the root with multipart/related as a child
   part was not structurally parsed correctly, producing incorrect parts when
   using [mimepart:get_simple_structure](../reference/mimepart/get_simple_structure.md).
   Thanks to @kayozaki! #506
 * typing.lua: couldn't distinguish `false` from unset for a boolean field with
   default of `true`, such as those used in `mail_auth.lua`. Thanks to
   @kayozaki! #505
 * Regression with `postmaster@domain` style addresses and null sender
   addresses when constructing messages via
   [kumo.make_message](../reference/kumo/make_message.md) and its equivalent
   internal API. Thanks in part to @kayozaki!  #511 #512
