<?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-13T00: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.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-13T00:00:00.000Z</updated>
        <content type="html"><![CDATA[
<h2>Features</h2>

<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-13T00: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>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.22.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-22-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-22-0"/>
        <updated>2025-12-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces support for arguments in user-defined operators, letting operators declare positional and named parameters with optional default values and use them just like built-in operators. It also enhances parser behavior for duplicate keys and includes several important stability, parsing, and retention improvements to make pipelines more flexible and reliable.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces support for arguments in user-defined operators, letting operators declare positional and named parameters with optional default values and use them just like built-in operators. It also enhances parser behavior for duplicate keys and includes several important stability, parsing, and retention improvements to make pipelines more flexible and reliable.</p>

<h2>Features</h2>

<h3>Argument support for User-defined operators</h3>
<p><small>Dec 17, 2025 · <a href="https://github.com/tobim">@tobim</a></small></p>
<p>User-defined operators in packages can now declare arguments in their YAML
frontmatter, enabling parameterized operator definitions with the same calling
convention as built-in operators.</p>
<p>Arguments can be positional or named. Both support optional default values and
can be called with literals, constant expressions, or dynamically evaluated
runtime expressions such as fields.</p>
<p>For example, create a reusable operator to set fields dynamically:</p>
<pre><code class="language-yaml">---
description: "Set a field to a value"
args:
  positional:
    - name: field
      type: field
    - name: value
      type: string
  named:
    - name: prefix
      type: string
      default: ""
---
$field = $prefix + $value
</code></pre>
<p>Use the operator with both constant and runtime arguments:</p>
<pre><code class="language-tql">from {x: 1}
mypkg::set_field this.name, "Alice", prefix="User: "
</code></pre>
<pre><code class="language-tql">{
  x: 1,
  name: "User: Alice",
}
</code></pre>
<p>Parameters can be typed with a type name passed in the namesake field. In case
the passed in expression can be evaluated at instantiation time it is checked
against the type and a diagnostic is returned if it does not match. In case a
type check is not possible because the expression contains references to
run-time data, the type check is omitted, and potential errors will be flagged at
runtime. Field-path arguments (declared via <code>type: field</code>) accept selectors and
cannot declare defaults.</p>

<h3>Filter files by modification times with `max_age`</h3>
<p><small>Dec 16, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5611">#5611</a></small></p>
<p>The <code>from_file</code>, <code>from_s3</code>, <code>from_gcs</code>, and <code>from_azure_blob_storage</code> operators
now support an optional <code>max_age</code> parameter that filters files based on their
last modification time. Only files modified within the specified duration from
now will be processed.</p>
<p><strong>Example</strong></p>
<p>Process only files modified in the last hour:</p>
<pre><code class="language-tql">from_file "/var/log/security/*.json", max_age=1h
</code></pre>

<h3>Improved Google Cloud PubSub Integration</h3>
<p><small>Dec 15, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5593">#5593</a></small></p>
<p>We have improved our Google Cloud PubSub integration with the addition of the new
<code>from_google_cloud_pubsub</code> and <code>to_google_cloud_pubsub</code> operators.</p>
<p>These operators are direct <em>void -> event</em> and <em>event -> void</em> operators, which
means that they ensure a 1:1 relation between events and messages.</p>
<p>The <code>from_google_cloud_pubsub</code> operator can also attach metadata such
as message ID, publish time, and attributes for downstream enrichment.</p>
<p>The legacy <code>load_google_cloud_pubsub</code> and <code>save_google_cloud_pubsub</code> operators
are deprecated in favor of these event-preserving counterparts.</p>

<h3>Backpressure and connection limits for HTTP server</h3>
<p><small>Dec 12, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5601">#5601</a></small></p>
<p>The <code>from_http</code> operator in server mode now implements backpressure, waiting for
each request to be processed before accepting new data. This prevents memory
pressure during traffic spikes from webhook integrations or log receivers.</p>
<p>A new <code>max_connections</code> parameter limits simultaneous connections:</p>
<pre><code class="language-tql">from_http "0.0.0.0:8080", server=true, max_connections=50
</code></pre>
<p>The default is 10 connections. Additional connections are rejected until a slot
frees up, keeping your pipelines stable under heavy load.</p>

<h3>Getting data from SentinelOne Data Lake</h3>
<p><small>Dec 12, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5599">#5599</a></small></p>
<p>The new <code>from_sentinelone_data_lake</code> operator allows you to query the SentinelOne
Singularity Data Lake using PowerQuery and retrieve security events directly into
your Tenzir pipelines. Tenzir's integrations with SentinelOne now allow you to
send data to <em>and</em> load data from SentinelOne Data Lakes.</p>
<p><strong>Example</strong></p>
<p>Query threat events and filter by severity:</p>
<pre><code class="language-tql">from_sentinelone_data_lake "https://xdr.eu1.sentinelone.net",
  token=secret("sentinelone-token"),
  query="severity > 3 | columns id",
  start=now()-7d
</code></pre>
<p>The operator sends a request to the <code>/api/powerQuery</code> endpoint with optional time
range filters and parses the tabular response into events for downstream processing.</p>

<h3>Support for duplicate keys in parsers</h3>
<p><small>Dec 8, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5445">#5445</a></small></p>
<p>Our parsers now have improved support for repeated keys in a an event.
Previously a later key-value pair would always overwrite the previous one.
With this change the value is transparently upgraded to a list of values.</p>

<h3>Getting Kafka records with `from_kafka`</h3>
<p><small>Dec 4, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5575">#5575</a></small></p>
<p>The new <code>from_kafka</code> operator allows you to receive one event per Kafka message,
thus keeping the event boundary unlike <code>load_kafka</code>, which has now been
deprecated.</p>
<p><strong>Example</strong></p>
<p>Use <code>from_kafka</code> to parse JSON events from a topic:</p>
<pre><code class="language-tql">from_kafka "events"
this = message.parse_json()
</code></pre>

<h3>Support GOOGLE_CLOUD_PROJECT environment variable in `to_google_cloud_logging` operator</h3>
<p><small>Dec 3, 2025 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5591">#5591</a></small></p>
<p>The <code>to_google_cloud_logging</code> operator now checks for the <code>GOOGLE_CLOUD_PROJECT</code> environment variable
if no explicit project id is given, before falling back to the Google Metadata service.</p>

<h3>Run pipelines with uvx tenzir</h3>
<p><small>Oct 27, 2025 · <a href="https://github.com/tobim">@tobim</a></small></p>
<p>The <code>tenzir</code> binary is now bundled directly with the <code>tenzir</code> Python wheel.
This means you can run Tenzir pipelines on any machine with uv installed,
without any separate installation steps.</p>
<p>Just use <code>uvx</code>:</p>
<pre><code class="language-bash">uvx tenzir 'version'
</code></pre>
<p>The bundled binary is available for Apple Silicon Macs, aarch64 Linux, and
x86_64 Linux. On other platforms, the wheel only contains the Python bindings
and you need to install the <code>tenzir</code> binary separately.</p>

<h2>Changes</h2>

<h3>Simplified `publish` and `subscribe` connection</h3>
<p><small>Dec 16, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5597">#5597</a></small></p>
<p>We made an under-the-hood change to the <code>publish</code> and <code>subscribe</code> implementation
that reduces the overhead when publishing to high-throughput topics.</p>

<h3>Removed `gcps://` URI scheme</h3>
<p><small>Dec 15, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5593">#5593</a></small></p>
<p>We have removed the <code>gcps:/</code> URI scheme, which previously would dispatch to
<code>load_google_cloud_pubsub</code> and <code>save_google_cloud_pubsub</code>. As these operators
are deprecated and will be removed, the schemas are being retired as well.</p>

<h3>Update default retention policies for metrics and diagnostics</h3>
<p><small>Dec 5, 2025 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5594">#5594</a></small></p>
<p>Tenzir now applies default retention policies for internal metrics and diagnostics:</p>
<ul>
<li><strong>Metrics</strong> (schema <code>tenzir.metrics.*</code>): Retained for 16 days by default</li>
<li><strong>Diagnostics</strong> (schema <code>tenzir.diagnostics.*</code>): Retained for 30 days by default</li>
</ul>
<p>These defaults help manage storage usage while keeping sufficient history for troubleshooting. You can customize these settings:</p>
<pre><code class="language-yaml"># tenzir.yaml
tenzir:
  retention:
    metrics: 16d      # Retention period for general metrics
    diagnostics: 30d  # Retention period for diagnostics
</code></pre>
<p>Set any retention period to <code>0</code> to disable automatic deletion for that category.</p>

<h2>Bug Fixes</h2>

<h3>Fixed an assertion in parsers</h3>
<p><small>Dec 8, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5595">#5595</a></small></p>
<p>When parsing typed-data (e.g. integers in JSON), with a predefined schema that
expected a different type (e.g. a <code>time</code>), the parser would crash with an
assertion failure.</p>
<p>This has now been resolved and the field will simply be null instead with a
warning being emitted.</p>

<h3>Fixed missing Zeek fields</h3>
<p><small>Dec 8, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5445">#5445</a></small></p>
<p>Zeek JSON contains fields such as <code>io.data.read.bytes</code> and
<code>io.data.read.bytes.per-second</code>. These fields would previously overwrite each other
in order of appearance.</p>
<p>With this change <code>bytes</code> now is a record and the original value is kept under the
key <code>""</code>.</p>

<h3>Removed warning for `void` metrics</h3>
<p><small>Dec 8, 2025 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5598">#5598</a></small></p>
<p>The non-actionable warning "received an operator metric without a unit" that was
sometimes emitted for closed subpipelines was removed.</p>

<h3>Fixed an assertion failure in parsers</h3>
<p><small>Dec 3, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5590">#5590</a></small></p>
<p>We fixed a bug in a common component used across all parsers, which could enter
an inconsistent state, leading to an "unexpected internal error: unreachable".</p>
]]></content>
        <published>2025-12-16T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.21.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-21-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-21-2"/>
        <updated>2025-11-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This is a bugfix release that fixes timestamp handling in the python operator and the backpressure handling in publish and subscribe.]]></summary>
        <content type="html"><![CDATA[<p>This is a bugfix release that fixes timestamp handling in the python operator and the backpressure handling in publish and subscribe.</p>

<h2>Bug Fixes</h2>

<h3>Fixed pubsub back-pressure</h3>
<p><small>Nov 28, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5587">#5587</a></small></p>
<p>We fixed a bug in the back-pressure propagation across <code>publish</code> and <code>subscribe</code>,
that could cause pipelines to stall.</p>

<h3>Fixed timestamp handling in the python operator</h3>
<p><small>Nov 28, 2025 · <a href="https://github.com/tobim">@tobim</a> · <a href="https://github.com/tenzir/tenzir/pull/5581">#5581</a></small></p>
<p>We addressed an issue that caused the python operator to fail when it received
data containing timestamp values.</p>
]]></content>
        <published>2025-11-28T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.21.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-21-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-21-1"/>
        <updated>2025-11-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release features new and improved hash functions as well as a couple of bugfixes.]]></summary>
        <content type="html"><![CDATA[<p>This release features new and improved hash functions as well as a couple of bugfixes.</p>

<h2>Features</h2>

<h3>OpenSSL hash backend and SHA3 functions</h3>
<p><small>Nov 20, 2025 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5574">#5574</a></small></p>
<p>All <code>hash_*</code> functions (MD5/SHA1/SHA2) now use OpenSSL's EVP implementation
instead of the previous digestpp copies. We've also added SHA3-224/256/384/512
variants to the <code>hash_*</code> family.</p>
<p>Here's how you compute a SHA3 hash digest:</p>
<pre><code class="language-tql">from {x: hash_sha3_256("foo")}
</code></pre>
<pre><code class="language-tql">{x: "76d3bc41c9f588f7fcd0d5bf4718f8f84b1c41b20882703100b9eb9413807c01"}
</code></pre>

<h2>Bug Fixes</h2>

<h3>Fixed `write_parquet`</h3>
<p><small>Nov 24, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5582">#5582</a></small></p>
<p>In the last release we introduced a bug that made the <code>write_parquet</code> operator
exit early without writing the file. This has now been fixed.</p>

<h3>Fixed assertion failure in `to_hive`</h3>
<p><small>Nov 24, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5582">#5582</a></small></p>
<p>We addressed an assertion failure in the <code>to_hive</code> operator, which could fail
the partitioned writes for some data and format combinations.</p>
]]></content>
        <published>2025-11-24T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.21.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-21-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-21-0"/>
        <updated>2025-11-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release improves the stability of pipelines by applying backpressure more effectively, ensuring upstream components slow down before overwhelming subscribers. It also enhances daily operations by improving parquet reliability, adding Base58 support, and extending the built-in OCSF operators and functions to support the newly released OCSF 1.7.0.]]></summary>
        <content type="html"><![CDATA[<p>This release improves the stability of pipelines by applying backpressure more effectively, ensuring upstream components slow down before overwhelming subscribers. It also enhances daily operations by improving parquet reliability, adding Base58 support, and extending the built-in OCSF operators and functions to support the newly released OCSF 1.7.0.</p>

<h2>Features</h2>

<h3>Improved Encoding and Decoding Support</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5572">#5572</a></small></p>
<p>We have added two new functions: <code>encode_base58</code> and <code>decode_base58</code>. As the names
imply, these Base58 encode/decode <code>string</code> or <code>blob</code> values, just like the already
existing functions for Base64, Hex or URL encoding.</p>
<p>With this change, we also enabled the usage of all encoding and decoding functions
on <code>secret</code> values.</p>

<h3>Support for OCSF v1.7.0</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5580">#5580</a></small></p>
<p>Tenzir now supports the newly released OCSF version 1.7.0.</p>

<h2>Changes</h2>

<h3>Parse time to UNIX epoch</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5571">#5571</a></small></p>
<p>The <code>parse_time()</code> function would earlier default to <code>1900</code> when the year was
unspecified. This has now been changed to <code>1970</code> to match the assumptions about
epoch in other parts of the language.</p>

<h3>Easier multi-key deduplication</h3>
<p><small>Nov 14, 2025 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5570">#5570</a></small></p>
<p>We now support multiple keys for deduplication, e.g., <code>deduplicate a, b.c, d</code>
is now equivalent to the previously unwieldy expression <code>deduplicate {x: a, y: b.c, z: d}</code>.</p>

<h2>Bug Fixes</h2>

<h3>Improved parquet support</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5579">#5579</a></small></p>
<p>We fixed a crash when performing some operations on data read from external
parquet files, such as Amazon Security Lake.</p>

<h3>Backpressure in `publish` and `subscribe`</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5568">#5568</a></small></p>
<p>Previously, the backpressure mechanism in <code>publish</code> and <code>subscribe</code> was not
working as intended. Thus, publishing pipelines continued processing data
even when downstream consumers were lagging far behind. This is now fixed. As a
result, memory consumption for pipelines connected by <code>publish</code> and <code>subscribe</code>
is reduced significantly in those cases.</p>

<h3>Fixed a race in concurrent function application</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/tobim">@tobim</a> · <a href="https://github.com/tenzir/tenzir/pull/5578">#5578</a></small></p>
<p>We fixed a race condition in case multiple pipelines used the same
transformation on the same data, such as string manipulations in where clauses
to filter the input. The bug caused those pipelines to fail sporadically.</p>

<h3>Gracefully handle server errors in the web plugin</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/tobim">@tobim</a> · <a href="https://github.com/tenzir/tenzir/pull/5577">#5577</a></small></p>
<p>The node now prints a proper error message in case the builtin web server can't start because the port is already in use.</p>
]]></content>
        <published>2025-11-19T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.20.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-20-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-20-2"/>
        <updated>2025-11-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release backports the changes made in v5.21.1 to v5.20.1.]]></summary>
        <content type="html"><![CDATA[<p>This release backports the changes made in v5.21.1 to v5.20.1.</p>

<h2>Bug Fixes</h2>

<h3>Fixed `write_parquet`</h3>
<p><small>Nov 24, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5582">#5582</a></small></p>
<p>In the last release we introduced a bug that made the <code>write_parquet</code> operator
exit early without writing the file. This has now been fixed.</p>

<h3>Fixed assertion failure in `to_hive`</h3>
<p><small>Nov 24, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5582">#5582</a></small></p>
<p>We addressed an assertion failure in the <code>to_hive</code> operator, which could fail
the partitioned writes for some data and format combinations.</p>

<h3>Improved parquet support</h3>
<p><small>Nov 19, 2025 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5579">#5579</a></small></p>
<p>We fixed a crash when performing some operations on data read from external
parquet files, such as Amazon Security Lake.</p>
]]></content>
        <published>2025-11-25T00:00:00.000Z</published>
    </entry>
</feed>