<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://docs.tenzir.com/changelog/tenzir</id>
    <title>Tenzir Node Changelog</title>
    <updated>2026-03-31T00:00:00.000Z</updated>
    <generator>Tenzir Changelog</generator>
    <author>
        <name>Tenzir</name>
        <uri>https://tenzir.com</uri>
    </author>
    <link rel="alternate" href="https://docs.tenzir.com/changelog/tenzir"/>
    <link rel="self" href="https://docs.tenzir.com/changelog/tenzir.xml"/>
    <subtitle>Release notes and changelog for Tenzir Node</subtitle>
    <icon>https://docs.tenzir.com/favicon.svg</icon>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.30.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-30-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-30-0"/>
        <updated>2026-03-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds OIDC web identity authentication for AWS operators, so you can assume AWS roles from external identity providers without long-lived credentials. It also speeds up logical and conditional expression evaluation and fixes several crashes and configuration diagnostics.]]></summary>
        <content type="html"><![CDATA[<p>This release adds OIDC web identity authentication for AWS operators, so you can assume AWS roles from external identity providers without long-lived credentials. It also speeds up logical and conditional expression evaluation and fixes several crashes and configuration diagnostics.</p>

<h2>Features</h2>

<h3>OIDC web identity authentication for AWS operators</h3>
<p><small>Feb 4, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5703">#5703</a></small></p>
<p>AWS operators now support OIDC-based authentication via the <code>AssumeRoleWithWebIdentity</code> API.</p>
<p>You can authenticate with AWS resources using OpenID Connect tokens from external identity providers like Azure, Google Cloud, or custom endpoints. This enables secure cross-cloud authentication without sharing long-lived AWS credentials.</p>
<p>Configure web identity authentication in any AWS operator by specifying a token source and target role:</p>
<pre><code>from_s3 "s3://bucket/path", aws_iam={
  region: "us-east-1",
  assume_role: "arn:aws:iam::123456789012:role/cross-cloud-role",
  web_identity: {
    token_file: "/path/to/oidc/token"
  }
}
</code></pre>
<p>The <code>web_identity</code> option accepts three token sources: <code>token_file</code> (path to a token file), <code>token_endpoint</code> (HTTP endpoint that returns a token), or <code>token</code> (direct token value). For HTTP endpoints, you can extract tokens from JSON responses using <code>path</code>.</p>
<p>Credentials automatically refresh before expiration, with exponential backoff retry logic for transient failures. This is especially useful for long-running pipelines that need persistent authentication.</p>

<h2>Changes</h2>

<h3>Faster evaluation of logical and conditional expressions</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5954">#5954</a></small></p>
<p>Pipelines that use <code>and</code>, <code>or</code>, or <code>if</code>-<code>else</code> expressions run significantly faster in certain cases — up to <strong>30×</strong> in our benchmarks. The improvement is most noticeable in pipelines with complex filtering or branching logic. No pipeline changes are needed to benefit.</p>

<h3>OCSF 1.8.0 support in ocsf::derive</h3>
<p><small>Mar 23, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5939">#5939</a></small></p>
<p>The <code>ocsf::derive</code> operator now supports OCSF <code>1.8.0</code> events.</p>
<p>For example, you can now derive enum and sibling fields for events that declare
<code>metadata.version: "1.8.0"</code>:</p>
<pre><code class="language-tql">from {metadata: {version: "1.8.0"}, class_uid: 1007}
ocsf::derive
</code></pre>
<p>This keeps OCSF normalization pipelines working when producers emit <code>1.8.0</code>
events.</p>

<h3>Platform configuration error message</h3>
<p><small>Feb 10, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5341">#5341</a></small></p>
<p>Platform configuration validation now provides clearer error messages when an invalid configuration is encountered, helping you quickly diagnose and fix configuration issues.</p>

<h2>Bug Fixes</h2>

<h3>Fix crash when connecting to unresolvable host</h3>
<p><small>Mar 26, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5827">#5827</a></small></p>
<p>Setting <code>TENZIR_ENDPOINT</code> to an unresolvable hostname no longer crashes the pipeline with a segfault.</p>

<h3>Spurious warning for Other (99) enum sibling in ocsf::derive</h3>
<p><small>Mar 25, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5949">#5949</a></small></p>
<p><code>ocsf::derive</code> no longer emits a false warning when an <code>_id</code> field is set
to <code>99</code> (Other) and the sibling string contains a source-specific value.</p>
<p>Per the OCSF specification, <code>99</code>/Other is an explicit escape hatch: the
integer signals that the value is not in the schema's enumeration and the
companion string <strong>must</strong> hold the raw value from the data source. For
example, the following is now accepted silently:</p>
<pre><code class="language-tql">from {
  metadata: { version: "1.7.0" },
  type_uid: 300201,
  class_uid: 3002,
  auth_protocol_id: 99,
  auth_protocol: "Negotiate",
}
ocsf::derive
</code></pre>
<p>Previously this produced a spurious <code>warning: found invalid value for 'auth_protocol'</code> because <code>"Negotiate"</code> is not a named enum caption.</p>

<h3>Fix crash on Azure SSL/transport errors</h3>
<p><small>Mar 24, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>The Azure Blob Storage connector now handles <code>Azure::Core::Http::TransportException</code>
(e.g., SSL certificate errors) gracefully instead of crashing. Previously, a
self-signed certificate in the certificate chain would cause an unhandled
exception and terminate the node.</p>
]]></content>
        <published>2026-03-31T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.29.4]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-29-4</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-29-4"/>
        <updated>2026-03-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release hardens container manifest publishing in GitHub Actions by switching the reusable manifest workflow to the workflow token with correctly paired registry credentials. It also avoids exposing registry secrets on the command line by using stdin-based Docker logins.]]></summary>
        <content type="html"><![CDATA[<p>This patch release hardens container manifest publishing in GitHub Actions by switching the reusable manifest workflow to the workflow token with correctly paired registry credentials. It also avoids exposing registry secrets on the command line by using stdin-based Docker logins.</p>
]]></content>
        <published>2026-03-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.29.3]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-29-3</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-29-3"/>
        <updated>2026-03-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release keeps the 5.29 line moving with a small maintenance update and validates the refreshed release automation. It ships as a clean follow-up release without additional user-facing changes.]]></summary>
        <content type="html"><![CDATA[<p>This patch release keeps the 5.29 line moving with a small maintenance update and validates the refreshed release automation. It ships as a clean follow-up release without additional user-facing changes.</p>
]]></content>
        <published>2026-03-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.29.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-29-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-29-2"/>
        <updated>2026-03-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release fixes several correctness and performance issues across parsing, querying, and storage, and completes Suricata 8 schema coverage.]]></summary>
        <content type="html"><![CDATA[<p>This patch release fixes several correctness and performance issues across parsing, querying, and storage, and completes Suricata 8 schema coverage.</p>

<h2>Features</h2>

<h3>Add store origin metadata to feather files</h3>
<p><small>Mar 17, 2026 · <a href="https://github.com/tobim">@tobim</a></small></p>
<p>Feather store files now include a <code>TENZIR:store:origin</code> key in the Arrow table
schema metadata. The value is <code>"ingest"</code> for freshly ingested data, <code>"rebuild"</code>
for partitions created by the rebuild command, and <code>"compaction"</code> for partitions
created by the compaction plugin. This allows external tooling such as <code>pyarrow</code>
to distinguish how a partition was produced.</p>

<h3>Improved Clickhouse Usability</h3>
<p><small>Mar 11, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/codex">@codex</a>, <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5897">#5897</a></small></p>
<p>The <code>to_clickhouse</code> operator now supports dynamic table names via an expression
<code>table=...</code>, which must evaluate to a <code>string</code>. If the value is not a valid
table name, the events will be dropped with a warning.</p>
<p>With this change, the operator will also create a database if it does not exist.</p>
<p>The prime use-case for this are OCSF event streams:</p>
<pre><code class="language-tql">subscribe "ocsf"
ocsf::cast encode_variants=true, null_fill=true
to_clickhouse table=f"ocsf.{class_name.replace(" ","_")}", ...
</code></pre>

<h3>Install Tenzir via Homebrew on macOS</h3>
<p><small>Mar 8, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5876">#5876</a></small></p>
<p>You can now install Tenzir on Apple Silicon macOS via Homebrew:</p>
<pre><code class="language-sh">brew tap tenzir/tenzir
brew install --cask tenzir
</code></pre>
<p>You can also install directly without tapping first:</p>
<pre><code class="language-sh">brew install --cask tenzir/tenzir/tenzir
</code></pre>
<p>The release workflow keeps the Homebrew cask in sync with the signed macOS
package so installs and uninstalls stay current across releases.</p>

<h2>Changes</h2>

<h3>Correct AWS Marketplace container image</h3>
<p><small>Mar 19, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5925">#5925</a></small></p>
<p>The AWS Marketplace ECR repository <code>tenzir-node</code> was incorrectly populated with
the <code>tenzir</code> image. It now correctly ships <code>tenzir-node</code>, which runs a Tenzir
node by default.</p>
<p>If you relied on the previous behavior, you can restore it by setting <code>tenzir</code>
as a custom entrypoint in your ECS task definition.</p>

<h3>Add Suricata schema types for IKE, HTTP2, PGSQL, and Modbus</h3>
<p><small>Mar 17, 2026 · <a href="https://github.com/tobim">@tobim</a> · <a href="https://github.com/tenzir/tenzir/pull/5914">#5914</a></small></p>
<p>The bundled Suricata schema now covers the remaining event types listed in the
Suricata 8.0.3 EVE JSON format documentation: IKE (IKEv1/IKEv2), HTTP/2,
PostgreSQL, and Modbus. This completes Suricata 8 schema coverage for Tenzir.</p>

<h2>Bug Fixes</h2>

<h3>Support long syslog structured-data parameter names</h3>
<p><small>Mar 19, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>read_syslog</code> operator and <code>parse_syslog</code> function now accept RFC 5424 structured-data parameter names longer than 32 characters, which some vendors emit despite the specification limit.</p>
<p>For example, this message now parses successfully instead of being rejected:</p>
<pre><code class="language-text">&#x3C;134>1 2026-03-18T11:00:51.194137+01:00 HOSTNAME abc 9043 23003147 [F5@12276 thx_f5_for_ignoring_the_32_char_limit_in_structured_data="thx"] broken example
</code></pre>
<p>This improves interoperability with vendor syslog implementations that exceed the RFC limit for structured-data parameter names.</p>

<h3>Fix batch timeout to flush asynchronously</h3>
<p><small>Mar 14, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5906">#5906</a></small></p>
<p>The batch timeout was only checked when a new event arrived, so a single event
followed by an idle stream would never be emitted. The timeout now fires
independently of upstream activity.</p>

<h3>Fix parse_winlog batch splitting</h3>
<p><small>Mar 13, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5901">#5901</a></small></p>
<p>The <code>parse_winlog</code> function could fragment output into thousands of tiny
batches due to type conflicts in <code>RenderingInfo/Keywords</code>, where events with
one <code>&#x3C;Keyword></code> emitted a string but events with multiple emitted a list.
Additionally, <code>EventData</code> with unnamed <code>&#x3C;Data></code> elements is now always emitted
as a record with <code>_0</code>, <code>_1</code>, etc. as field names instead of a list.</p>

<h3>Optimize `in` operator and fix eq/neq null semantics</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5899">#5899</a></small></p>
<p>The <code>in</code> operator for list expressions is up to 33x faster. Previously it
created and finalized entire Arrow arrays for every element comparison, causing
severe overhead for expressions like <code>EventID in [5447, 4661, ...]</code>.</p>
<p>Additionally, comparing a typed null value with <code>==</code> now returns <code>false</code> instead
of <code>null</code>, and <code>!=</code> returns <code>true</code>, fixing a correctness issue with null
handling in equality comparisons.</p>

<h3>Fix secret comparison bypass in `in` operator fast path</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5899">#5899</a></small></p>
<p>The <code>in</code> operator fast path now correctly prevents comparison of secret values.
Previously, <code>secret_value in [...]</code> would silently compare instead of returning
null with a warning, bypassing the established secret comparison policy.</p>

<h3>Fix pattern equality ignoring case-insensitive flag</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5900">#5900</a></small></p>
<p>Pattern equality checks now correctly consider the case-insensitive flag.
Previously, two patterns that differed only in case sensitivity were treated as
equal, violating the hash/equality contract.</p>

<h3>Fix over-reservation in partition_array for string/blob types</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5899">#5899</a></small></p>
<p>Splitting Arrow arrays for string and blob types no longer over-reserves memory.
Previously both output builders reserved the full input size each, using up to
twice the necessary memory.</p>
]]></content>
        <published>2026-03-19T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.29.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-29-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-29-1"/>
        <updated>2026-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a scheduling issue introduced in v5.24.0 that could cause the node to become unresponsive when too many pipelines using detached operators were deployed simultaneously.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a scheduling issue introduced in v5.24.0 that could cause the node to become unresponsive when too many pipelines using detached operators were deployed simultaneously.</p>

<h2>Bug Fixes</h2>

<h3>Scheduling issue with detached operators</h3>
<p><small>Mar 16, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5895">#5895</a></small></p>
<p>Fixed a scheduling issue introduced in v5.24.0 that could cause the node to
become unresponsive when too many pipelines using detached operators like
<code>from_udp</code> were deployed simultaneously.</p>
]]></content>
        <published>2026-03-16T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.29.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-29-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-29-0"/>
        <updated>2026-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release improves log ingestion by extracting structured data from legacy syslog messages and aligning the bundled schema with Suricata 8. It also republishes the previous release after an error in the earlier release process.]]></summary>
        <content type="html"><![CDATA[<p>This release improves log ingestion by extracting structured data from legacy syslog messages and aligning the bundled schema with Suricata 8. It also republishes the previous release after an error in the earlier release process.</p>

<h2>Features</h2>

<h3>Add Suricata schema types for IKE, HTTP2, PGSQL, and Modbus</h3>
<p><small>Mar 17, 2026 · <a href="https://github.com/tobim">@tobim</a> · <a href="https://github.com/tenzir/tenzir/pull/5914">#5914</a></small></p>
<p>The bundled Suricata schema now includes types for four previously missing event types: <code>ike</code>, <code>http2</code>, <code>pgsql</code>, and <code>modbus</code>.</p>
<p>The <code>ike</code> type supports both IKEv1 and IKEv2 traffic. Version-specific fields are contained within dedicated <code>ikev1</code> and <code>ikev2</code> sub-objects, covering key exchange payloads, nonce payloads, client proposals, vendor IDs, and IKEv2 role/notify information.</p>
<p>The <code>http2</code> type models HTTP/2 request and response streams including settings frames, header lists, error codes, and stream priority.</p>
<p>The <code>pgsql</code> type covers PostgreSQL session events with full request fields (simple queries, startup parameters, SASL authentication) and response fields (row counts, command completion, parameter status).</p>
<p>The <code>modbus</code> type captures industrial Modbus protocol transactions including function codes, access types, exception responses, diagnostic subfunctions, and MEI encapsulated interface data.</p>

<h3>Extract structured data from legacy syslog content</h3>
<p><small>Mar 13, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5902">#5902</a></small></p>
<p><code>read_syslog</code> and <code>parse_syslog</code> now extract a leading RFC 5424-style
structured-data block from RFC 3164 message content.</p>
<p>This pattern occurs in practice with some VMware ESXi messages, where
components such as <code>Hostd</code> emit a legacy syslog record and prepend structured
metadata before the human-readable message text.</p>
<p>For example, this raw syslog line:</p>
<pre><code class="language-text">&#x3C;166>2026-02-11T18:01:45.587Z esxi-01.example.invalid Hostd[2099494]: [Originator@6876 sub=Vimsvc.TaskManager opID=11111111-2222-3333-4444-555555555555] Task Completed
</code></pre>
<p>now parses as:</p>
<pre><code class="language-tql">{
  facility: 20,
  severity: 6,
  timestamp: "2026-02-11T18:01:45.587Z",
  hostname: "esxi-01.example.invalid",
  app_name: "Hostd",
  process_id: "2099494",
  structured_data: {
    "Originator@6876": {
      sub: "Vimsvc.TaskManager",
      opID: "11111111-2222-3333-4444-555555555555",
    },
  },
  content: "Task Completed",
}
</code></pre>
<p>Events without extracted structured data keep the existing <code>syslog.rfc3164</code>
schema. Events with extracted structured data use
<code>syslog.rfc3164.structured</code>.</p>

<h3>Support for Suricata 8 schema</h3>
<p><small>Mar 10, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/satta">@satta</a> · <a href="https://github.com/tenzir/tenzir/pull/5888">#5888</a></small></p>
<p>The bundled Suricata schema now aligns with Suricata 8, enabling proper parsing and representation of events from Suricata 8 deployments.</p>
<p>This update introduces support for new event types including POP3, ARP, and BitTorrent DHT, along with enhancements to existing event types. QUIC events now include <code>ja4</code> and <code>ja4s</code> fields for fingerprinting, DHCP events include <code>vendor_class_identifier</code>, and TLS certificate timestamps now use the precise <code>time</code> type instead of string representation.</p>
<p>These schema changes ensure that Tenzir can reliably ingest and process telemetry from Suricata 8 without data loss or type mismatches.</p>

<h2>Bug Fixes</h2>

<h3>Fix pipeline startup timeouts</h3>
<p><small>Mar 11, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5893">#5893</a></small></p>
<p>In some situations, pipelines could not be successfully started, leading to
timeouts and a non-responsive node, especially during node start.</p>

<h3>Prevent where/map assertion crash on sliced list batches</h3>
<p><small>Mar 10, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5886">#5886</a></small></p>
<p>Pipelines using chained list transforms such as <code>xs.where(...).map(...).where(...)</code> no longer trigger an internal assertion on sliced input batches.</p>

<h3>Graceful handling of Google Cloud Pub/Sub authentication errors</h3>
<p><small>Mar 9, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5877">#5877</a></small></p>
<p>Invalid Google Cloud credentials in <code>from_google_cloud_pubsub</code> no longer crash the node. Authentication errors now surface as operator diagnostics instead.</p>
]]></content>
        <published>2026-03-16T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.28.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-28-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-28-0"/>
        <updated>2026-03-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds support for parsing Check Point syslog structured-data dialects that deviate from RFC 5424, improving out-of-the-box interoperability with Check Point exports. It also makes DNS hostname resolution in the load_tcp operator opt-in and fixes several parser bugs related to schema changes between events.]]></summary>
        <content type="html"><![CDATA[<p>This release adds support for parsing Check Point syslog structured-data dialects that deviate from RFC 5424, improving out-of-the-box interoperability with Check Point exports. It also makes DNS hostname resolution in the load_tcp operator opt-in and fixes several parser bugs related to schema changes between events.</p>

<h2>Features</h2>

<h3>Check Point syslog structured-data dialect parsing</h3>
<p><small>Mar 2, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5851">#5851</a></small></p>
<p><code>parse_syslog()</code> and <code>read_syslog</code> now accept common Check Point structured-data variants that are not strictly RFC 5424 compliant. This includes <code>key:"value"</code> parameters, semicolon-separated parameters, and records that omit an SD-ID entirely.</p>
<p>For records without an SD-ID, Tenzir now normalizes the structured data under <code>checkpoint_2620</code>, so downstream pipelines can use a stable field path.</p>
<p>For example, the message <code>&#x3C;134>1 ... - [action:"Accept"; conn_direction:"Incoming"]</code> now parses successfully and maps to <code>structured_data.checkpoint_2620</code>. This improves interoperability with Check Point exports and reduces ingestion-time preprocessing.</p>

<h2>Changes</h2>

<h3>JSON parse error context</h3>
<p><small>Mar 6, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5805">#5805</a></small></p>
<p>JSON parsing errors now display the surrounding bytes at the error location. This
makes it easier to diagnose malformed JSON in your data pipelines.</p>
<p>For example, if your JSON is missing a closing bracket, the error message shows
you the bytes around that location and marks where the parser stopped expecting
more input.</p>

<h3>DNS hostname resolution opt-in for load_tcp operator</h3>
<p><small>Mar 4, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5865">#5865</a></small></p>
<p>The <code>load_tcp</code> operator now makes DNS hostname resolution opt-in with the <code>resolve_hostnames</code> parameter (defaults to <code>false</code>).</p>
<p>Previously, the operator always attempted reverse DNS lookups for peer endpoints, which could fail in environments without working reverse DNS configurations. Now you can enable this behavior by setting <code>resolve_hostnames</code> to <code>true</code>:</p>
<pre><code class="language-tql">load_tcp endpoint="0.0.0.0:5555" resolve_hostnames=true {
  read_json
}
</code></pre>
<p>When enabled and DNS resolution fails, the operator emits a warning diagnostic (once) instead of failing. This allows the operator to continue functioning in environments where reverse DNS is unavailable or unreliable.</p>

<h2>Bug Fixes</h2>

<h3>Uncaught exception reporting</h3>
<p><small>Mar 6, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5805">#5805</a></small></p>
<p>We improved the reporting for unexpected diagnostics outside of operator execution,
such as during startup. In these cases you will now get the diagnostic message.</p>

<h3>Parser bug fixes for schema changes</h3>
<p><small>Mar 6, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5805">#5805</a></small></p>
<p>Fixed multiple issues that could cause errors or incorrect behavior when the
schema of parsed events changes between records. This is particularly important
when ingesting data from sources that may add, remove, or modify fields over time.</p>
<p>Schema mismatch warnings for repeated fields in JSON objects (which Tenzir
interprets as lists) now include an explanatory hint, making it clearer what's
happening when a field appears multiple times where a single value was expected.</p>
]]></content>
        <published>2026-03-06T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.27.3]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-27-3</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-27-3"/>
        <updated>2026-03-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a crash that could occur when reading JSON data. It also improves CEF parsing to handle non-conforming unescaped equals characters.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a crash that could occur when reading JSON data. It also improves CEF parsing to handle non-conforming unescaped equals characters.</p>

<h2>Bug Fixes</h2>

<h3>JSON reading crash fix</h3>
<p><small>Mar 2, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5855">#5855</a></small></p>
<p>We fixed a bug that could cause a crash when reading JSON data.</p>

<h3>Fix CEF parsing for unescaped equals</h3>
<p><small>Mar 2, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5841">#5841</a></small></p>
<p>The CEF parser now handles unescaped <code>=</code> characters (which are not conforming to
the specification) by using a heuristic.</p>
]]></content>
        <published>2026-03-03T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.27.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-27-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-27-2"/>
        <updated>2026-02-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds the hmac function for computing Hash-based Message Authentication Codes over strings and blobs. It also fixes an assertion failure in array slicing that was introduced in v5.27.0.]]></summary>
        <content type="html"><![CDATA[<p>This release adds the hmac function for computing Hash-based Message Authentication Codes over strings and blobs. It also fixes an assertion failure in array slicing that was introduced in v5.27.0.</p>

<h2>Features</h2>

<h3>Add `hmac` function</h3>
<p><small>Feb 27, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5846">#5846</a></small></p>
<p>The new experimental <code>hmac</code> function computes Hash-based Message
Authentication Codes (HMAC) for strings and blobs. It supports SHA-256
(default), SHA-512, SHA-384, SHA-1, and MD5 algorithms.</p>
<p>Note: The <code>key</code> parameter is currently a plain string because function
arguments cannot be secrets yet. We plan to change this in the future.</p>
<pre><code class="language-tql">from {
  signature: hmac("hello world", "my-secret-key"),
}
</code></pre>
<pre><code class="language-tql">{
  signature: "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad",
}
</code></pre>
<p>Specify a different algorithm with the <code>algorithm</code> parameter:</p>
<pre><code class="language-tql">from {
  signature: hmac("hello world", "my-secret-key", algorithm="sha512"),
}
</code></pre>

<h2>Bug Fixes</h2>

<h3>Fixed an assertion failure in slicing</h3>
<p><small>Feb 27, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5842">#5842</a></small></p>
<p>We fixed a bug that would cause an assertion failure <em>"Index error: array slice would exceed array length"</em>.
This was introduced as part of an optimization in Tenzir Node v5.27.0.</p>
]]></content>
        <published>2026-02-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.27.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-27-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-27-1"/>
        <updated>2026-02-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes an issue where the platform plugin did not correctly use the configured certfile, keyfile, and cafile options for client certificate authentication.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes an issue where the platform plugin did not correctly use the configured certfile, keyfile, and cafile options for client certificate authentication.</p>

<h2>Bug Fixes</h2>

<h3>Fix platform plugin not respecting `certfile` and `keyfile` options</h3>
<p><small>Feb 24, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>Fixed in issue where the platform plugin did not correctly use the
configured <code>certfile</code>, <code>keyfile</code> and <code>cafile</code> options for client
certificate authentication, and improved the error messages for TLS
issues during platform connection.</p>
]]></content>
        <published>2026-02-25T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.27.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-27-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-27-0"/>
        <updated>2026-02-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release enhances the sort function with custom comparators and descending order support, and extends the slice function to work with lists.]]></summary>
        <content type="html"><![CDATA[<p>This release enhances the sort function with custom comparators and descending order support, and extends the slice function to work with lists.</p>

<h2>Features</h2>

<h3>Slice function extended to support lists</h3>
<p><small>Feb 22, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5819">#5819</a></small></p>
<p>The <code>slice</code> function now supports <code>list</code> types in addition to <code>string</code>. You can slice lists using the same <code>begin</code>, <code>end</code>, and <code>stride</code> parameters. Negative stride values are now supported for lists, letting you reverse or step backward through list data. String slicing continues to require a positive <code>stride</code>.</p>
<p>Example usage with lists:</p>
<ul>
<li><code>[1, 2, 3, 4, 5].slice(begin=1, end=4)</code> returns <code>[2, 3, 4]</code></li>
<li><code>[1, 2, 3, 4, 5].slice(stride=-1)</code> returns the list in reverse order</li>
<li><code>[1, 2, 3, 4, 5].slice(begin=1, end=5, stride=-2)</code> returns <code>[5, 3]</code></li>
</ul>

<h3>Enhance `sort` function with `desc` and `cmp` parameters</h3>
<p><small>Feb 17, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5767">#5767</a></small></p>
<p>The <code>sort</code> function now supports two new parameters: <code>desc</code> for controlling
sort direction and <code>cmp</code> for custom comparison logic via binary lambdas.</p>
<p><strong>Sort in descending order:</strong></p>
<pre><code class="language-tql">from {xs: [3, 1, 2]}
select ys = sort(xs, desc=true)
</code></pre>
<pre><code class="language-tql">{ys: [3, 2, 1]}
</code></pre>
<p><strong>Sort records by a specific field using a custom comparator:</strong></p>
<pre><code class="language-tql">from {xs: [{v: 2, id: "b"}, {v: 1, id: "a"}, {v: 2, id: "c"}]}
select ys = sort(xs, cmp=(left, right) => left.v &#x3C; right.v)
</code></pre>
<pre><code class="language-tql">{
  ys: [
    {v: 1, id: "a"},
    {v: 2, id: "b"},
    {v: 2, id: "c"},
  ],
}
</code></pre>
<p>The <code>cmp</code> lambda receives two elements and returns a boolean indicating whether
the first element should come before the second. Both parameters can be combined
to reverse a custom comparison.</p>

<h2>Bug Fixes</h2>

<h3>Fix `read_lines` operator for old executor</h3>
<p><small>Feb 17, 2026 · <a href="https://github.com/tobim">@tobim</a></small></p>
<p>The <code>read_lines</code> operator was accidently broken while it was ported
to the new execution API. This change restores its functionality.</p>

<h3>HTTP header values can contain colons</h3>
<p><small>Jan 28, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5693">#5693</a></small></p>
<p>HTTP header values containing colons are now parsed correctly.</p>
]]></content>
        <published>2026-02-24T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.26.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-26-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-26-0"/>
        <updated>2026-02-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces the from_mysql operator for reading data directly from MySQL databases, with support for live streaming, custom SQL queries, and TLS connections. It also adds link-based HTTP pagination and optional field parameters for user-defined operators.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces the from_mysql operator for reading data directly from MySQL databases, with support for live streaming, custom SQL queries, and TLS connections. It also adds link-based HTTP pagination and optional field parameters for user-defined operators.</p>

<h2>Features</h2>

<h3>Optional field parameters for user-defined operators</h3>
<p><small>Feb 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5753">#5753</a></small></p>
<p>User-defined operators in packages can now declare optional field-type parameters with <code>null</code> as the default value. This allows operators to accept field selectors that are not required to be provided.</p>
<p>When a field parameter is declared with <code>type: field</code> and <code>default: null</code>, you can omit the argument when calling the operator, and the parameter will receive a <code>null</code> value instead. You can then check whether a field was provided by comparing the parameter to <code>null</code> within the operator definition.</p>
<p>Example:</p>
<p>In your package's operator definition, declare an optional field parameter:</p>
<pre><code class="language-yaml">args:
  named:
    - name: selector
      type: field
      default: null
</code></pre>
<p>In the operator implementation, check if the field was provided:</p>
<pre><code class="language-tql">set result = if $selector != null then "field provided" else "field omitted"
</code></pre>
<p>When calling the operator, the field argument becomes optional:</p>
<pre><code class="language-tql">my_operator                    # field is null
my_operator selector=x.y       # field is x.y
</code></pre>
<p>Only <code>null</code> is allowed as the default value for field parameters. Non-null defaults are rejected with an error during package loading.</p>

<h3>Link header pagination for HTTP operators</h3>
<p><small>Feb 11, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The <code>paginate</code> parameter for the <code>from_http</code> and <code>http</code> operators now supports link-based pagination via the <code>Link</code> HTTP header.</p>
<p>Previously, pagination was only available through a lambda function that extracted the next URL from response data. Now you can use <code>paginate="link"</code> to automatically follow pagination links specified in the response's <code>Link</code> header, following RFC 8288. This is useful for APIs that use HTTP header-based pagination instead of embedding next URLs in the response body.</p>
<p>The operator parses the <code>Link</code> header and follows the <code>rel=next</code> relation to automatically fetch the next page of results.</p>
<p>Example:</p>
<pre><code>from_http "https://api.example.com/data", paginate="link"
</code></pre>
<p>If an invalid pagination mode is provided (neither a lambda nor <code>"link"</code>), the operator now reports a clear error message.</p>

<h3>MySQL source operator</h3>
<p><small>Feb 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5721">#5721</a>, <a href="https://github.com/tenzir/tenzir/pull/5738">#5738</a></small></p>
<p>The <code>from_mysql</code> operator lets you read data directly from MySQL databases.</p>
<p>Read a table:</p>
<pre><code class="language-tql">from_mysql table="users", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>List tables:</p>
<pre><code class="language-tql">from_mysql show="tables", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>Show columns:</p>
<pre><code class="language-tql">from_mysql table="users", show="columns", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>And ultimately execute a custom SQL query:</p>
<pre><code class="language-tql">from_mysql sql="SELECT id, name FROM users WHERE active = 1",
           host="localhost",
           port=3306,
           user="admin",
           password="secret",
           database="mydb"
</code></pre>
<p>The operator supports TLS/SSL connections for secure communication with MySQL
servers. Use <code>tls=true</code> for default TLS settings, or pass a record for
fine-grained control:</p>
<pre><code class="language-tql">from_mysql table="users", host="db.example.com", database="prod", tls={
  cacert: "/path/to/ca.pem",
  certfile: "/path/to/client-cert.pem",
  keyfile: "/path/to/client-key.pem",
}
</code></pre>
<p>The operator supports MySQL's <code>caching_sha2_password</code> authentication method and automatically maps MySQL data types to Tenzir types.</p>
<p>Use <code>live=true</code> to continuously stream new rows from a table. The operator
tracks progress using a watermark on an integer column, polling for rows above
the last-seen value:</p>
<pre><code class="language-tql">from_mysql table="events", live=true, host="localhost", database="mydb"
</code></pre>
<p>By default, the tracking column is auto-detected from the table's
auto-increment primary key. To specify one explicitly:</p>
<pre><code class="language-tql">from_mysql table="events", live=true, tracking_column="event_id",
           host="localhost", database="mydb"
</code></pre>

<h2>Bug Fixes</h2>

<h3>Improve write_lines operator performance</h3>
<p><small>Feb 12, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a></small></p>
<p>We have significantly improved the performance of the <code>write_lines</code> operator.</p>

<h3>Secret type support for user-defined operator parameters</h3>
<p><small>Feb 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5752">#5752</a></small></p>
<p>User-defined operators in packages can now declare parameters with the <code>secret</code> type to ensure that secret values are properly handled as secret expressions:</p>
<pre><code>args:
  positional:
    - name: api_key
      type: secret
      description: "API key to use for authentication"
</code></pre>

<h3>merge() function recursive deep merge for nested records</h3>
<p><small>Feb 5, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5728">#5728</a></small></p>
<p>The <code>merge()</code> function now performs a recursive deep merge when merging two records. Previously, nested fields were dropped when merging, so <code>merge({hw: {sn: "XYZ123"}}, {hw: {model: "foobar"}})</code> would incorrectly produce <code>{hw: {model: "foobar"}}</code> instead of recursively merging the nested fields. The function now correctly produces <code>{hw: {sn: "XYZ123", model: "foobar"}}</code> by materializing both input records and performing a deep merge on them.</p>
]]></content>
        <published>2026-02-13T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.25.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-25-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-25-2"/>
        <updated>2026-02-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes the sigma operator to correctly load all rule files from a directory.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes the sigma operator to correctly load all rule files from a directory.</p>

<h2>Bug Fixes</h2>

<h3>Fix sigma operator directory handling to load all rules</h3>
<p><small>Feb 3, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5715">#5715</a></small></p>
<p>The <code>sigma</code> operator now correctly loads all rules when given a directory containing multiple Sigma rule files. Previously, only the last processed rule file would be retained because the rules collection was being cleared on every recursive directory traversal.</p>
<pre><code class="language-tql">sigma "/path/to/sigma/rules"
</code></pre>
<p>All rules found in the directory and its subdirectories will now be loaded and used to match against input events.</p>
]]></content>
        <published>2026-02-09T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.25.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-25-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-25-1"/>
        <updated>2026-01-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release includes several bug fixes for the JSON parser, `where`, `replace`, and `if` operators, along with Kafka decompression support and a new `raw_message` option for the `read_syslog` operator.]]></summary>
        <content type="html"><![CDATA[<p>This release includes several bug fixes for the JSON parser, <code>where</code>, <code>replace</code>, and <code>if</code> operators, along with Kafka decompression support and a new <code>raw_message</code> option for the <code>read_syslog</code> operator.</p>

<h2>Features</h2>

<h3>Raw message field support for read_syslog operator</h3>
<p><small>Jan 27, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5687">#5687</a></small></p>
<p>The <code>read_syslog</code> operator now supports a <code>raw_message</code> parameter that preserves the original, unparsed syslog message in a field of your choice. This is useful when you need to retain the exact input for auditing, debugging, or compliance purposes.</p>
<p>When you specify <code>raw_message=&#x3C;field></code>, the operator stores the complete input message (including all lines for multiline messages) in the specified field. This works with all syslog formats, including RFC 5424, RFC 3164, and octet-counted messages.</p>
<p>For example:</p>
<pre><code class="language-tql">read_syslog raw_message=original_input
</code></pre>
<p>This stores the unparsed message in the <code>original_input</code> field alongside the parsed structured fields like <code>hostname</code>, <code>app_name</code>, <code>message</code>, and others.</p>

<h2>Bug Fixes</h2>

<h3>Fix overzealous constant evaluation in `if` statements</h3>
<p><small>Jan 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5701">#5701</a></small></p>
<p>The condition of <code>if</code> statements is no longer erroneously evaluated early when
it contains a lambda expression that references runtime fields.</p>

<h3>Support decompression for Kafka operators</h3>
<p><small>Jan 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5697">#5697</a></small></p>
<p>Kafka connectors now support decompressing messages with <code>zstd</code>, <code>lz4</code> and <code>gzip</code>.</p>

<h3>Fix intermittent UTF-8 errors in JSON parser</h3>
<p><small>Jan 29, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5698">#5698</a></small></p>
<p>The JSON parser no longer intermittently fails with "The input is not valid UTF-8"
when parsing data containing multi-byte UTF-8 characters such as accented letters
or emojis.</p>

<h3>Fix assertion failure in replace operator when replacing with null</h3>
<p><small>Jan 29, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5696">#5696</a></small></p>
<p>The <code>replace</code> operator no longer triggers an assertion failure when using
<code>with=null</code> on data processed by operators like <code>ocsf::cast</code>.</p>
<pre><code class="language-tql">load_file "dns.json"
read_json
ocsf::cast "dns_activity"
replace what="", with=null
</code></pre>

<h3>Where operator optimization for optional fields</h3>
<p><small>Jan 28, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The <code>where</code> operator optimization now correctly handles optional fields marked with <code>?</code>. Previously, the optimizer didn't account for the optional marker, which could result in incorrect query optimization. This fix ensures that optional field accesses are handled properly without affecting the optimization of regular field accesses.</p>
]]></content>
        <published>2026-01-30T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.25.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-25-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-25-0"/>
        <updated>2026-01-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds periodic emission to the summarize operator, enabling real-time streaming analytics with configurable intervals and accumulation modes. It also introduces AWS IAM authentication across SQS, S3, and Kafka operators, and fixes memory instability in from_http when used with slow downstream consumers.]]></summary>
        <content type="html"><![CDATA[<p>This release adds periodic emission to the summarize operator, enabling real-time streaming analytics with configurable intervals and accumulation modes. It also introduces AWS IAM authentication across SQS, S3, and Kafka operators, and fixes memory instability in from_http when used with slow downstream consumers.</p>

<h2>Features</h2>

<h3>Periodic emission for summarize operator</h3>
<p><small>Jan 22, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5605">#5605</a></small></p>
<p>The <code>summarize</code> operator now supports periodic emission of aggregation results at fixed intervals, enabling real-time streaming analytics and monitoring use cases.</p>
<p>Use the <code>options</code> named argument with <code>frequency</code> to emit results every N seconds:</p>
<pre><code class="language-tql">summarize count(this), src_ip, options={frequency: 5s}
</code></pre>
<p>This emits aggregation results every 5 seconds, showing the count per source IP for events received during each interval:</p>
<pre><code class="language-tql">{src_ip: 192.168.1.1, count: 42}
{src_ip: 192.168.1.2, count: 17}
// ... 5 seconds later ...
{src_ip: 192.168.1.1, count: 38}
{src_ip: 192.168.1.3, count: 9}
</code></pre>
<p>The <code>mode</code> parameter controls how aggregations behave across emissions:</p>
<p><strong>Reset mode</strong> (default) resets aggregations after each emission, providing per-interval metrics:</p>
<pre><code class="language-tql">summarize sum(bytes), options={frequency: 10s}
// Shows bytes per 10-second window
</code></pre>
<p><strong>Cumulative mode</strong> accumulates values across emissions, providing running totals:</p>
<pre><code class="language-tql">summarize sum(bytes), options={frequency: 10s, mode: "cumulative"}
// Shows total bytes seen so far
</code></pre>
<p><strong>Update mode</strong> emits only when values change from the previous emission, reducing output noise in monitoring scenarios:</p>
<pre><code class="language-tql">summarize count(this), severity, options={frequency: 1s, mode: "update"}
// Emits only when the count for a severity level changes
</code></pre>
<p>The operator always emits final results when the input stream ends, ensuring no data is lost.</p>

<h3>AWS IAM authentication for load_sqs, save_sqs, from_s3, to_s3, from_kafka, and to_kafka</h3>
<p><small>Jan 21, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5675">#5675</a></small></p>
<p>The <code>load_sqs</code>, <code>save_sqs</code>, <code>from_s3</code>, <code>to_s3</code>, <code>from_kafka</code>, and <code>to_kafka</code> operators now support AWS IAM authentication through a new <code>aws_iam</code> option. You can configure explicit credentials, assume IAM roles, use AWS CLI profiles, or rely on the default credential chain.</p>
<p>The <code>aws_iam</code> option accepts these fields:</p>
<ul>
<li><code>profile</code>: AWS CLI profile name for credential resolution</li>
<li><code>access_key_id</code>: AWS access key ID</li>
<li><code>secret_access_key</code>: AWS secret access key</li>
<li><code>session_token</code>: AWS session token for temporary credentials</li>
<li><code>assume_role</code>: IAM role ARN to assume</li>
<li><code>session_name</code>: Session name for role assumption</li>
<li><code>external_id</code>: External ID for role assumption</li>
</ul>
<p>Additionally, the SQS and Kafka operators accept a top-level <code>aws_region</code> option:</p>
<ul>
<li>For <code>load_sqs</code> and <code>save_sqs</code>: Configures the AWS SDK client region for queue URL resolution</li>
<li>For <code>from_kafka</code> and <code>to_kafka</code>: Required for MSK authentication (used to construct the authentication endpoint URL)</li>
</ul>
<p>You can also combine explicit credentials with role assumption. This uses the provided credentials to call STS AssumeRole and obtain temporary credentials for the assumed role:</p>
<pre><code class="language-tql">load_sqs "my-queue", aws_iam={
  access_key_id: "AKIAIOSFODNN7EXAMPLE",
  secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  assume_role: "arn:aws:iam::123456789012:role/my-role"
}
</code></pre>
<p>For example, to load from SQS with a specific region:</p>
<pre><code class="language-tql">load_sqs "my-queue", aws_region="us-east-1", aws_iam={
  access_key_id: "AKIAIOSFODNN7EXAMPLE",
  secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
</code></pre>
<p>To use an AWS CLI profile:</p>
<pre><code class="language-tql">load_sqs "my-queue", aws_iam={
  profile: "production"
}
</code></pre>
<p>To assume an IAM role:</p>
<pre><code class="language-tql">from_s3 "s3://bucket/path", aws_iam={
  assume_role: "arn:aws:iam::123456789012:role/my-role",
  session_name: "tenzir-session",
  external_id: "unique-id"
}
</code></pre>
<p>For Kafka MSK authentication, the <code>aws_region</code> option is required:</p>
<pre><code class="language-tql">from_kafka "my-topic", aws_region="us-east-1", aws_iam={
  profile: "production"
}
</code></pre>
<p>When no explicit credentials or profile are configured, operators use the AWS SDK's default credential provider chain, which checks environment variables (<code>AWS_ACCESS_KEY_ID</code>, <code>AWS_SECRET_ACCESS_KEY</code>), AWS configuration files (<code>~/.aws/credentials</code>), EC2/ECS instance metadata, and other standard sources. This applies both when <code>aws_iam</code> is omitted entirely and when <code>aws_iam</code> is specified without <code>access_key_id</code>, <code>secret_access_key</code>, or <code>profile</code>.</p>

<h3>RFC 6587 octet-counting support for syslog parsing</h3>
<p><small>Jan 21, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The <code>parse_syslog</code> function now supports RFC 6587 octet-counted framing, where syslog messages are prefixed with their byte length (for example, <code>65 &#x3C;syslog-message></code>). This framing is commonly used in TCP-based syslog transport to handle message boundaries.</p>
<p>The new <code>octet_counting</code> parameter for <code>parse_syslog</code> offers three modes:</p>
<ul>
<li><strong>Not specified (default)</strong>: Auto-detect. The parser strips a length prefix if present and valid, otherwise parses the input as-is. This prevents false positives where input coincidentally starts with digits and a space.</li>
<li><strong><code>octet_counting=true</code></strong>: Require a length prefix. Emits a warning and returns null if the input lacks a valid prefix.</li>
<li><strong><code>octet_counting=false</code></strong>: Never strip a length prefix. Parse the input as-is.</li>
</ul>

<h3>Per-actor memory allocation tracking</h3>
<p><small>Jan 12, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5646">#5646</a></small></p>
<p>We have added support for per-actor/per-thread allocation tracking. When enabled, these stats will track which actor
(or thread) allocated how much memory. This gives much more detailed insights into where memory is allocated.
By default these detailed statistics are not collected, as they introduce a cost to every allocation.</p>

<h2>Changes</h2>

<h3>Preserve original field order in ocsf::derive</h3>
<p><small>Jan 20, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5673">#5673</a></small></p>
<p>The <code>ocsf::derive</code> operator now preserves original field order instead of
reordering alphabetically. Derived enum/sibling pairs are inserted at the
position of the first field, ordered alphabetically within each pair (e.g.,
<code>activity_id</code> before <code>activity_name</code>). Non-OCSF fields remain at their original
positions.</p>
<p>For example, given the input:</p>
<pre><code class="language-tql">{foo: 1, class_uid: 1001}
</code></pre>
<p>The output is now:</p>
<pre><code class="language-tql">{foo: 1, class_name: "...", class_uid: 1001}
</code></pre>
<p>Previously, the output was alphabetically sorted:</p>
<pre><code class="language-tql">{class_name: "...", class_uid: 1001, foo: 1}
</code></pre>

<h3>Cleanup of existing directory markers in from_s3 and from_abs</h3>
<p><small>Jan 19, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5670">#5670</a></small></p>
<p>The <code>from_s3</code> and <code>from_azure_blob_storage</code> operators now also delete existing
directory marker objects along the glob path when <code>remove=true</code>. Directory
markers are zero-byte objects with keys ending in <code>/</code> that some cloud storage
tools create. These artifacts can accumulate over time, increasing API costs and
slowing down listing operations.</p>

<h2>Bug Fixes</h2>

<h3>Stable memory usage for `from_http` server</h3>
<p><small>Jan 23, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5677">#5677</a></small></p>
<p>The <code>from_http</code> server now has a stable memory usage when used with a slow
downstream, especially in situations where the client timeouts and retries
requests.</p>

<h3>Phantom pipeline entries with empty IDs</h3>
<p><small>Jan 22, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5680">#5680</a></small></p>
<p>In rare cases, a phantom pipeline with an empty ID could appear in the pipeline list that couldn't be deleted through the API.</p>

<h3>Correct multi-partition commits in `from_kafka`</h3>
<p><small>Jan 12, 2026 · <a href="https://github.com/raxyte">@raxyte</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5654">#5654</a></small></p>
<p>The <code>from_kafka</code> operator now commits offsets per partition and tracks partition
EOFs based on the current assignment, preventing premature exits and
cross-partition replays after restarts.</p>

<h3>No more directory markers for S3 and Azure</h3>
<p><small><a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5669">#5669</a></small></p>
<p>Deleting files from S3 or Azure Blob Storage via <code>from_s3</code> or
<code>from_azure_blob_storage</code> with the <code>remove=true</code> option no longer creates empty
directory marker objects in the parent directory when the last file of the
directory is deleted.</p>
]]></content>
        <published>2026-01-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.24.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-24-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-24-0"/>
        <updated>2026-01-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds XML parsing functions (`parse_xml` and `parse_winlog`) for analyzing XML-formatted logs including Windows Event Logs. It also introduces the `parallel` operator for parallel pipeline execution, fixes a socket leak in `from_http` that could cause resource exhaustion, and includes several stability fixes for gRPC operators and the pipeline API.]]></summary>
        <content type="html"><![CDATA[<p>This release adds XML parsing functions (<code>parse_xml</code> and <code>parse_winlog</code>) for analyzing XML-formatted logs including Windows Event Logs. It also introduces the <code>parallel</code> operator for parallel pipeline execution, fixes a socket leak in <code>from_http</code> that could cause resource exhaustion, and includes several stability fixes for gRPC operators and the pipeline API.</p>

<h2>Features</h2>

<h3>Per-pipeline memory consumption metrics</h3>
<p><small>Jan 5, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5644">#5644</a></small></p>
<p>The new <code>tenzir.metrics.operator_buffers</code> metrics track the total bytes and
events buffered across all operators of a pipeline. The metrics are emitted
every second and include:</p>
<ul>
<li><code>timestamp</code>: The point in time when the data was recorded</li>
<li><code>pipeline_id</code>: The pipeline's unique identifier</li>
<li><code>bytes</code>: Total bytes currently buffered</li>
<li><code>events</code>: Total events currently buffered (for events only)</li>
</ul>
<p>Use <code>metrics "operator_buffers"</code> to access these metrics.</p>

<h3>XML parsing functions for TQL</h3>
<p><small>Dec 30, 2025 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5640">#5640</a>, <a href="https://github.com/tenzir/tenzir/pull/5645">#5645</a></small></p>
<p>The new <code>parse_xml</code> and <code>parse_winlog</code> functions parse XML strings into structured records, enabling analysis of XML-formatted logs and data sources.</p>
<p>The <code>parse_xml</code> function offers flexible XML parsing with XPath-based element selection, configurable attribute handling, namespace management, and depth limiting. It supports multiple match results as lists and handles both simple and complex XML structures.</p>
<p>The <code>parse_winlog</code> function specializes in parsing Windows Event Log XML format, automatically finding Event elements and transforming EventData/UserData sections into properly structured fields.</p>
<p>Both functions integrate with Tenzir's multi-series builder for schema inference and type handling.</p>

<h3>Easy parallel pipeline execution</h3>
<p><small>Dec 23, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5632">#5632</a></small></p>
<p>The <code>parallel</code> operator executes a pipeline across multiple parallel pipeline
instances to improve throughput for computationally expensive operations. It
automatically distributes input events across the pipeline instances and merges
their outputs back into a single stream.</p>
<p>Use the <code>jobs</code> parameter to specify how many pipeline instances to spawn.
For example, to parse JSON in parallel across 4 pipeline instances:</p>
<pre><code class="language-tql">from_file "input.ndjson"
read_lines
parallel 4 {
  this = line.parse_json()
}
</code></pre>

<h2>Changes</h2>

<h3>Duplicate diagnostics only suppressed for 4 hours</h3>
<p><small>Jan 12, 2026 · <a href="https://github.com/raxyte">@raxyte</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5652">#5652</a></small></p>
<p>Repeated warnings and errors now resurface every 4 hours instead of being suppressed forever. Previously, once a diagnostic was shown, it would never appear again even if the underlying issue persisted. This change helps users notice recurring problems that may require attention.</p>

<h3>Event-based rate limiting for throttle operator</h3>
<p><small>Jan 9, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5642">#5642</a></small></p>
<p>The <code>throttle</code> operator now rate-limits events instead of bytes. Use the <code>rate</code>
option to specify the maximum number of events per window, <code>weight</code> to assign
custom per-event weights, and <code>drop</code> to discard excess events instead of
waiting. The operator also emits metrics for dropped events.</p>

<h2>Bug Fixes</h2>

<h3>Unresponsive pipeline API</h3>
<p><small>Jan 15, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5651">#5651</a></small></p>
<p>Previously, it was possible for the node to enter a state where the internal
pipeline API was no longer responding, thus rendering the platform unresponsive.</p>

<h3>Crashes during gRPC operator shutdown</h3>
<p><small>Jan 14, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5661">#5661</a></small></p>
<p>We fixed bugs in several gRPC-based operators:</p>
<ul>
<li>A potential crash in <code>from_velociraptor</code> on shutdown.</li>
<li>Potentially not publishing final messages in <code>to_google_cloud_pubsub</code> on
shutdown.</li>
<li>A concurrency bug in <code>from_google_cloud_pubsub</code> that could cause a crash.</li>
</ul>

<h3>Missing events when using `in` with `export`</h3>
<p><small>Jan 14, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5660">#5660</a></small></p>
<p>The <code>export</code> operator incorrectly skipped partitions when evaluating <code>in</code>
predicates with uncertain membership. This caused queries like
<code>export | where field in [values...]</code> to potentially miss matching events.</p>

<h3>Fixed `from_kafka` not producing events</h3>
<p><small>Jan 14, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5659">#5659</a></small></p>
<p>We fixed a bug in <code>from_kafka</code> that would cause it to not produce events.</p>

<h3>Socket leak in `from_http`</h3>
<p><small>Jan 8, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5647">#5647</a></small></p>
<p>The <code>from_http</code> operator sometimes left sockets in <code>CLOSE_WAIT</code> state instead of
closing them properly. This could lead to resource exhaustion on long-running
nodes receiving many HTTP requests.</p>

<h3>Timezone handling in static binary</h3>
<p><small>Jan 7, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5649">#5649</a></small></p>
<p>The <code>format_time</code> and <code>parse_time</code> functions in the static binary now correctly
use the operating system's timezone database.</p>

<h3>Error propagation in every and cron operators</h3>
<p><small>Dec 23, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5632">#5632</a></small></p>
<p>The <code>every</code> and <code>cron</code> operators now correctly propagate errors from their subpipelines instead of silently swallowing them.</p>
]]></content>
        <published>2026-01-16T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.23.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-23-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-23-1"/>
        <updated>2026-01-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes internal errors in expression evaluation for heterogeneous data, resolves a crash in the  operator when using , and ensures the  connector shuts down gracefully.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes internal errors in expression evaluation for heterogeneous data, resolves a crash in the  operator when using , and ensures the  connector shuts down gracefully.</p>

<h2>Bug Fixes</h2>

<h3>Length mismatch in expression evaluation for heterogeneous data</h3>
<p><small>Dec 31, 2025 · <a href="https://github.com/raxyte">@raxyte</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Expression evaluation could produce a length mismatch when processing heterogeneous data, potentially causing assertion failures. This affected various operations including binary and unary operators, field access, indexing, and aggregation functions.</p>

<h3>Assertion failure in deduplicate with count_field</h3>
<p><small>Dec 30, 2025 · <a href="https://github.com/raxyte">@raxyte</a></small></p>
<p>The <code>deduplicate</code> operator with <code>count_field</code> option could cause assertion failures when discarding events.</p>

<h3>Graceful shutdown for save_tcp connector</h3>
<p><small>Dec 29, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5637">#5637</a></small></p>
<p>The <code>save_tcp</code> connector now gracefully shuts down on pipeline stop and
connection failures. Previously, the connector could abort the entire
application on exit.</p>
]]></content>
        <published>2026-01-02T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.23.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-23-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-23-0"/>
        <updated>2025-12-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces centralized node-level TLS configuration, allowing you to configure TLS settings once in tenzir.yaml instead of passing options to each operator individually. It also adds support for event-timestamp-based compaction rules and a count field in the deduplicate operator.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces centralized node-level TLS configuration, allowing you to configure TLS settings once in tenzir.yaml instead of passing options to each operator individually. It also adds support for event-timestamp-based compaction rules and a count field in the deduplicate operator.</p>

<h2>Features</h2>

<h3>Use event timestamps for compaction rules</h3>
<p><small>Dec 23, 2025 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5629">#5629</a></small></p>
<p>Compaction rules can now use event timestamps instead of import time when selecting data by age. Configure this using the new optional <code>field</code> key in the compaction configuration.</p>
<p>Previously, compaction always used the import time to determine which partitions to compact. Now you can specify any timestamp field from your events:</p>
<pre><code class="language-yaml">tenzir:
  compaction:
    time:
      rules:
        - name: compact-old-logs
          after: 7d
          field: timestamp  # Use event timestamp instead of import time
          pipeline: |
            summarize count=count(), src_ip
</code></pre>
<p>When <code>field</code> is not specified, compaction continues to use import time for backward compatibility.</p>

<h3>Count dropped events in deduplicate operator</h3>
<p><small>Dec 22, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5622">#5622</a></small></p>
<p>The <code>deduplicate</code> operator now supports a <code>count_field</code> option that adds a field
to each output event showing how many events were dropped for that key.</p>
<p><strong>Example</strong></p>
<pre><code class="language-tql">from {x: 1, seq: 1}, {x: 1, seq: 2}, {x: 1, seq: 3}, {x: 1, seq: 4}
deduplicate x, distance=2, count_field=drop_count
</code></pre>
<pre><code class="language-tql">{x: 1, seq: 1, drop_count: 0}
{x: 1, seq: 4, drop_count: 2}
</code></pre>
<p>Events that are the first occurrence of a key or that trigger output after
expiration have a count of <code>0</code>.</p>

<h3>Platform TLS configuration</h3>
<p><small>Dec 17, 2025 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5559">#5559</a></small></p>
<p>The Tenzir Node now lets you configure the minimum TLS version and TLS ciphers
accepted for the connection to the Tenzir Platform:</p>
<pre><code class="language-yaml">plugins:
  platform:
    tls-min-version: "1.2"
    tls-ciphers: "HIGH:!aNULL:!MD5"
</code></pre>

<h3>Node-level TLS configuration for operators</h3>
<p><small>Dec 17, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5559">#5559</a></small></p>
<p>All operators and connectors that use TLS now support centralized node-level
configuration. Instead of passing TLS options to each operator individually,
you can configure them once in <code>tenzir.yaml</code> under <code>tenzir.tls</code>.</p>
<p>Arguments passed directly to the operator itself via an argument take precedence
over the configuration entry.</p>
<p>The following options are available:</p>
<ul>
<li><code>enable</code>: Enable TLS on all operators that support it</li>
<li><code>skip-peer-verification</code>: Disable certificate verification</li>
<li><code>cacert</code>: Path to a CA certificate bundle for server verification</li>
<li><code>certfile</code>: Path to a client certificate file</li>
<li><code>keyfile</code>: Path to a client private key file</li>
<li><code>tls-min-version</code>: Minimum TLS protocol version (<code>"1.0"</code>, <code>"1.1"</code>, <code>"1.2"</code>, or <code>"1.3"</code>)</li>
<li><code>tls-ciphers</code>: OpenSSL cipher list string</li>
</ul>
<p>The later two options have also been added as operator arguments.</p>
<p>For server-mode operators (<code>load_http server=true</code>, <code>load_tcp</code>), mutual TLS (mTLS)
authentication is now supported:</p>
<ul>
<li><code>tls-client-ca</code>: Path to a CA certificate for validating client certificates</li>
<li><code>tls-require-client-cert</code>: Require clients to present valid certificates</li>
</ul>
<p>These two options are also available as operator arguments.</p>
<p>Example configuration enforcing TLS 1.2+ with specific ciphers:</p>
<pre><code class="language-yaml">tenzir:
  tls:
    tls-min-version: "1.2"
    tls-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"
    cacert: "/etc/ssl/certs/ca-certificates.crt"
</code></pre>

<h2>Bug Fixes</h2>

<h3>Fixed default compaction rules for metrics and diagnostics</h3>
<p><small>Dec 23, 2025 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5629">#5629</a></small></p>
<p>The default compaction rules for <code>tenzir.metrics.*</code> and <code>tenzir.diagnostic</code> events now correctly use the <code>timestamp</code> field instead of import time.</p>
<p>Previously, these built-in compaction rules relied on import time to determine which events to compact, which could lead to inconsistent results as the import time is not computed per-event. As a result, it was possible that metrics and diagnostics were not deleted even though they expired.</p>
]]></content>
        <published>2025-12-23T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.22.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-22-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-22-2"/>
        <updated>2025-12-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a performance regression when parsing lists with mixed-type elements, where batch processing was inadvertently broken. It also resolves an assertion failure that could crash Tenzir when encountering events with duplicate keys.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a performance regression when parsing lists with mixed-type elements, where batch processing was inadvertently broken. It also resolves an assertion failure that could crash Tenzir when encountering events with duplicate keys.</p>

<h2>Bug Fixes</h2>

<h3>Fixed assertion failure when encountering duplicate keys</h3>
<p><small>Dec 19, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5612">#5612</a></small></p>
<p>We fixed an assertion failure and subsequent crash that could occur when parsing
events that contain duplicate keys.</p>

<h3>Improved Type Conflict Handling</h3>
<p><small>Dec 16, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5612">#5612</a></small></p>
<p>We resolved an issue that would appear when reading in lists (e.g. JSON <code>[]</code>)
where the elements had different types. Tenzir's type system at this time only
supports storing a single type in a list. Our parsers resolve this issue by first
attempting conversions (e.g. to a common numeric type) and turning all values
into strings as a last resort. Previously this would however also break Tenzir's
batch processing leading to significant performance loss. This has now been fixed.</p>
]]></content>
        <published>2025-12-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.22.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-22-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-22-1"/>
        <updated>2025-12-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a bug where the `publish` operator could drop events.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a bug where the <code>publish</code> operator could drop events.</p>

<h2>Bug Fixes</h2>

<h3>Fixed `publish` operator dropping events</h3>
<p><small>Dec 18, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5618">#5618</a></small></p>
<p>The <code>publish</code> operator could drop events during flush operations.
Events are now reliably delivered to subscribers.</p>
]]></content>
        <published>2025-12-18T00:00:00.000Z</published>
    </entry>
</feed>