<?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-05-22T00: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 v6.0.0-rc.6]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v6-0-0-rc-6</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v6-0-0-rc-6"/>
        <updated>2026-05-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir v6.0.0-rc.6 continues the rollout of the rewritten execution engine that unlocks faster, more capable, and more scalable pipelines. This release candidate includes breaking changes; use the migration guide at https://docs.tenzir.com/guides/tenzir-v6-migration when testing your workloads.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir v6.0.0-rc.6 continues the rollout of the rewritten execution engine that unlocks faster, more capable, and more scalable pipelines. This release candidate includes breaking changes; use the migration guide at https://docs.tenzir.com/guides/tenzir-v6-migration when testing your workloads.</p>

<h2>Breaking Changes</h2>

<h3>Renamed `from_gcs` to `from_google_cloud_storage`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5766">#5766</a></small></p>
<p>The <code>from_gcs</code> operator has been renamed to <code>from_google_cloud_storage</code> so
that its name matches the new <code>to_google_cloud_storage</code> writer:</p>
<pre><code class="language-tql">// Before:
from_gcs "gs://my-bucket/data/**.json"

// After:
from_google_cloud_storage "gs://my-bucket/data/**.json"
</code></pre>
<p>Update test suites that reference <code>from_gcs</code> in <code>requires.operators</code>
accordingly.</p>

<h3>`to_kafka` defaults to NDJSON-encoded messages</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5742">#5742</a></small></p>
<p>The default <code>message</code> expression of the <code>to_kafka</code> operator is now
<code>this.print_ndjson()</code> instead of <code>this.print_json()</code>. Kafka messages are
single-line records by default, so each event is now emitted as a single
NDJSON line:</p>
<pre><code class="language-json">{"timestamp":"2024-03-15T10:30:00.000000","source_ip":"192.168.1.100","alert_type":"brute_force"}
</code></pre>
<p>instead of pretty-printed multi-line JSON.</p>
<p>To restore the previous behavior, pass <code>message=this.print_json()</code>
explicitly.</p>

<h3>`yara` requires finite input</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6035">#6035</a></small></p>
<p>The <code>yara</code> operator no longer accepts the <code>blockwise</code> argument. Instead, it
buffers the entire input as one contiguous byte sequence and runs the YARA
scan when the input ends. Matches can therefore span chunk boundaries, but
<code>yara</code> is now only suitable for finite byte streams. Don't use it on
never-ending inputs.</p>
<p>The <code>rule</code> argument now also accepts a single string in addition to a list
of strings:</p>
<pre><code class="language-tql">from_file "evil.exe", mmap=true {
  yara "rule.yara"
}
</code></pre>
<p>Removed:</p>
<pre><code class="language-tql">yara ["rule.yara"], blockwise=true
</code></pre>

<h3>Removed `real_time` argument from `measure`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5880">#5880</a></small></p>
<p>The <code>measure</code> operator no longer accepts the <code>real_time</code> argument. The
operator's emission cadence is now governed entirely by the executor's
backpressure, so the option no longer has a meaningful effect.</p>
<p>Remove <code>real_time=true</code> or <code>real_time=false</code> from your pipelines:</p>
<pre><code class="language-tql">// Before:
measure real_time=true

// After:
measure
</code></pre>

<h3>`$file` let-binding for filesystem readers</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6001">#6001</a></small></p>
<p>The filesystem and cloud object reader operators (<code>from_file</code>, <code>from_s3</code>,
<code>from_azure_blob_storage</code>, <code>from_google_cloud_storage</code>) no longer accept the
<code>path_field</code> option. Instead, the parsing subpipeline now has access to a
<code>$file</code> let-binding describing the source file:</p>
<p>| Field   | Type     | Description                              |
| :------ | :------- | :--------------------------------------- |
| <code>path</code>  | <code>string</code> | The absolute path of the file being read |
| <code>mtime</code> | <code>time</code>   | The last modification time of the file   |</p>
<p>To attach the source path to each event:</p>
<pre><code class="language-tql">// Before:
from_file "/data/*.json", path_field=source

// After:
from_file "/data/*.json" {
  read_json
  source = $file.path
}
</code></pre>
<p>This makes per-file metadata available throughout the parsing subpipeline
rather than only on emitted events.</p>

<h3>`from_http` is now a pure HTTP client</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5953">#5953</a></small></p>
<p>The <code>from_http</code> operator no longer doubles as an HTTP server. It is now a
pure HTTP client that issues one request and returns the response.</p>
<p>For accepting incoming HTTP requests, use the dedicated <code>accept_http</code>
operator instead:</p>
<pre><code class="language-tql">// Before:
from_http "0.0.0.0:8080", server=true { read_json }

// After:
accept_http "0.0.0.0:8080" { read_json }
</code></pre>
<p>In the parsing subpipeline, the response metadata is now exposed as the
<code>$response</code> let-binding instead of being written into a <code>metadata_field</code>:</p>
<pre><code class="language-tql">from_http "https://api.example.com/status" {
  read_json
  status_code = $response.code
  server = $response.headers.Server
}
</code></pre>
<p>Additionally, the <code>url</code> and <code>headers</code> arguments are now resolved as
<a href="https://docs.tenzir.com/explanations/secrets">secrets</a>, so you can pass
secret names instead of hardcoding tokens or sensitive URLs.</p>

<h3>OpenSearch ingestion with `accept_opensearch`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6066">#6066</a></small></p>
<p>The new <code>accept_opensearch</code> operator starts an OpenSearch-compatible HTTP
server and turns incoming Bulk API requests into events:</p>
<pre><code class="language-tql">accept_opensearch "0.0.0.0:9200"
publish "events"
</code></pre>
<p>The operator buffers each bulk request body up to <code>max_request_size</code>,
optionally decompresses it based on the <code>Content-Encoding</code> header, parses the
NDJSON payload, and emits the resulting records. Set <code>keep_actions=true</code> to
also keep the OpenSearch action objects (e.g., <code>{"create": ...}</code>) in the
stream.</p>
<p>The <code>from_opensearch</code> operator has been removed. Use <code>accept_opensearch</code>
instead. The <code>elasticsearch://</code> and <code>opensearch://</code> URL schemes now dispatch
to <code>accept_opensearch</code> via <code>from</code>.</p>

<h3>Dedicated FTP source and sink operators</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6044">#6044</a></small></p>
<p>Two new operators provide first-class FTP and FTPS support with parsing and
printing subpipelines:</p>
<ul>
<li><code>from_ftp</code> downloads bytes from an FTP or FTPS server and forwards them to
the parsing subpipeline.</li>
<li><code>to_ftp</code> uploads bytes produced by the printing subpipeline to an FTP or
FTPS server.</li>
</ul>
<pre><code class="language-tql">from_ftp "ftp://user:pass@ftp.example.org/path/to/file.ndjson" {
  read_ndjson
}
</code></pre>
<pre><code class="language-tql">to_ftp "ftp://user:pass@ftp.example.org/a/b/c/events.ndjson" {
  write_ndjson
}
</code></pre>
<p>The <code>load_ftp</code> and <code>save_ftp</code> operators have been removed, and the <code>ftp://</code>
and <code>ftps://</code> URL schemes no longer dispatch via <code>from</code> and <code>to</code>. Use
<code>from_ftp</code> and <code>to_ftp</code> directly.</p>

<h2>Features</h2>

<h3>HEC queue selection in `to_splunk`</h3>
<p><small>May 18, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The neo <code>to_splunk</code> implementation now accepts <code>queue="indexing"</code> and
<code>queue="typing"</code> for selecting the Splunk HEC processing queue. The default
<code>indexing</code> path keeps Splunk's regular HEC behavior, while <code>typing</code> sends the
Splunk <code>parsingQueue</code> hint in HEC event envelopes for receivers that support
this non-standard HEC metadata.</p>
<p>The default is <code>queue="indexing"</code>. The <code>typing</code> queue is rejected with
<code>raw=...</code>, because Splunk's raw HEC endpoint sends raw requests to the indexer
queue.</p>

<h3>Add `auto_fill` option to `read_csv`, `read_tsv`, `read_ssv`, and `read_xsv`</h3>
<p><small>May 18, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The <code>read_csv</code>, <code>read_tsv</code>, <code>read_ssv</code>, and <code>read_xsv</code> operators now accept an
<code>auto_fill=true</code> option. When set, the parser silently fills missing trailing
columns with <code>null</code> instead of emitting a warning, which is useful when working
with feeds that legitimately omit optional trailing fields.</p>

<h3>Request records for `from_http` pagination</h3>
<p><small>May 17, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>from_http</code> operator now supports returning request records from
<code>paginate</code> lambdas. This lets APIs keep pagination state in the next request
body or headers instead of only in the next URL:</p>
<pre><code class="language-tql">from_http "https://opensearch.example.com/logs/_search",
  method="post",
  body={size: 500, query: {match_all: {}}},
  paginate=(x => {
    body: {
      size: 500,
      query: {match_all: {}},
      search_after: x.hits.hits[-1].sort,
    },
  } if x.hits.hits != []) {
  read_json
}
</code></pre>
<p>Returned request records can patch <code>url</code>, <code>method</code>, <code>headers</code>, and <code>body</code>.
Missing fields inherit from the current request, and <code>body: null</code> clears the
body.</p>

<h3>Prometheus shape for `metrics`</h3>
<p><small>May 16, 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/6190">#6190</a></small></p>
<p>The <code>metrics</code> operator now accepts <code>shape="prometheus"</code> to emit metrics from
metrics plugins as canonical <code>{metric, value, timestamp, labels, type, unit}</code>
records. The default remains <code>shape="raw"</code>, which preserves the existing
<code>tenzir.metrics.*</code> schemas.</p>

<h3>Raw byte output with write_all</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The new <code>write_all</code> operator concatenates one selected <code>string</code> or <code>blob</code> field
into raw bytes:</p>
<pre><code class="language-tql">from_file "/tmp/report.pdf" {
  read_all binary=true
}
to_file "/tmp/report-copy.pdf" {
  write_all data
}
</code></pre>
<p>Use it to copy binary payloads, reconstruct byte streams after event processing,
or write string fields without separators or escaping.</p>

<h3>Repeat string function</h3>
<p><small>May 15, 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/6181">#6181</a></small></p>
<p>The new <code>repeat</code> function repeats a string a given number of times:</p>
<pre><code class="language-tql">message = "na".repeat(8)
</code></pre>
<pre><code class="language-tql">{
  message: "nananananananana",
}
</code></pre>

<h3>`from_http` infers response parsers</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>from_http</code> operator now accepts requests without an explicit parser
subpipeline when Tenzir can infer the response format from the <code>Content-Type</code>
header or URL extension:</p>
<pre><code class="language-tql">from_http "https://example.com/events.json"
</code></pre>
<p>Explicit parser subpipelines continue to take precedence over inferred formats.</p>

<h3>CloudWatch Logs operators</h3>
<p><small>May 14, 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/6180">#6180</a></small></p>
<p>Tenzir now supports reading from and writing to CloudWatch Logs with the new
<code>from_amazon_cloudwatch</code> and <code>to_amazon_cloudwatch</code> operators. The source can
subscribe to live streams with <code>mode="live"</code>, search historical log groups with
<code>mode="search"</code>, or replay one stream with <code>mode="replay"</code>.</p>
<pre><code class="language-tql">from_amazon_cloudwatch "/aws/lambda/api", mode="search", filter="ERROR"
</code></pre>
<p>The default sink can send events with <code>PutLogEvents</code>, including configurable
batching, timestamp handling, parallel requests, and AWS IAM authentication via
<code>aws_iam</code>. The sink can also write to the CloudWatch HTTP ingestion endpoints by
setting <code>method</code> to <code>json</code>, <code>ndjson</code>, or <code>hlc</code>, with either SigV4 or bearer-token
authentication.</p>
<pre><code class="language-tql">to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  payload=message,
  timestamp=ts
</code></pre>

<h3>SQS receive controls</h3>
<p><small>May 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/6167">#6167</a>, <a href="https://github.com/tenzir/tenzir/pull/6174">#6174</a></small></p>
<p>The <code>from_sqs</code> operator now gives you explicit control over how messages are
received from SQS. Use <code>keep_messages=true</code> to inspect or replay messages
without removing them from the queue, <code>batch_size=&#x3C;1..10></code> to control how many
messages each receive request may return, and <code>visibility_timeout=&#x3C;duration></code> to
override the queue visibility timeout for received messages:</p>
<pre><code class="language-tql">from_sqs "events", keep_messages=true, batch_size=10, visibility_timeout=30s
</code></pre>
<p>By default, <code>from_sqs</code> keeps deleting each received message after emitting it.
With <code>keep_messages=true</code>, SQS makes the message visible again after the queue's
visibility timeout.</p>

<h3>Microsoft Graph source operator</h3>
<p><small>May 12, 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/6165">#6165</a>, <a href="https://github.com/tenzir/tenzir/pull/6179">#6179</a>, <a href="https://github.com/tenzir/tenzir/pull/6182">#6182</a></small></p>
<p>Tenzir now includes a Microsoft Graph source operator for reads from Microsoft Graph <code>v1.0</code> and <code>beta</code> collections with app-only Microsoft Entra authentication and OData pagination.</p>
<p>For example, you can read Entra ID sign-in logs with client credentials and push down OData query options:</p>
<pre><code class="language-tql">from_microsoft_graph "auditLogs/signIns",
  auth={
    tenant_id: "contoso.onmicrosoft.com",
    client_id: "00000000-0000-0000-0000-000000000000",
    client_secret: secret("ms-graph-client-secret"),
  },
  odata={
    filter: "createdDateTime ge 2026-04-24T00:00:00Z",
    select: ["id", "createdDateTime", "userPrincipalName", "status"],
    top: 1000,
  }
</code></pre>
<p>The operator emits each object from the response <code>value</code> array as a separate event and follows <code>@odata.nextLink</code> until the collection is exhausted.</p>
<p>The operator can also use Microsoft Graph delta queries with <code>delta=true</code>, storing the returned <code>@odata.deltaLink</code> in memory and polling it with a configurable <code>poll_interval</code>. OData query options apply to the initial delta request only, subject to Microsoft Graph's resource-specific support, and subsequent polls use the opaque delta link exactly as Microsoft Graph returned it.</p>
<p>It also retries throttled and transient Microsoft Graph requests, respecting <code>Retry-After</code> when present.</p>

<h3>Event throughput metrics for the new executor</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Pipeline metrics now report event throughput alongside byte throughput for
pipelines running on the new executor:</p>
<pre><code class="language-tql">metrics "pipeline"
summarize ingress_events=sum(ingress.events), ingress_bytes=sum(ingress.bytes), egress_events=sum(egress.events), pipeline_id
sort -egress_events
</code></pre>
<p>This makes node metrics distinguish the amount of data transferred from the
number of events processed.</p>

<h3>Internal memory size function</h3>
<p><small>May 8, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The new <code>internal_memory_size</code> function estimates the size of each event in
bytes:</p>
<pre><code class="language-tql">size = internal_memory_size(this)
</code></pre>
<p>This is useful for building pipelines that inspect or route events based on their approximate in-memory payload size.</p>

<h3>from_amqp queue arguments</h3>
<p><small>May 8, 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/6139">#6139</a></small></p>
<p><code>from_amqp</code> now accepts a <code>queue_arguments</code> record for RabbitMQ queue declaration arguments:</p>
<pre><code class="language-tql">from_amqp "amqp://broker/vhost",
          queue="events",
          queue_arguments={
            "x-queue-type": "quorum",
            "x-quorum-initial-group-size": 3
          }
</code></pre>
<p>Use this to declare queues with broker-specific settings such as quorum queues, maximum lengths, message TTLs, single active consumers, and dead-letter exchanges.</p>

<h3>TQL match statements</h3>
<p><small>May 2, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>TQL now supports statement-level <code>match</code> blocks for branching on patterns:</p>
<pre><code class="language-tql">match action {
  "accept" | "allow" => { verdict = "allowed" }
  "deny" | "drop" => { verdict = "blocked" }
  _ => { verdict = "unknown" }
}
</code></pre>
<p>Patterns can be constants, exclusive ranges, alternatives separated by <code>|</code>, or
the final wildcard <code>_</code>. Every <code>match</code> must include an unguarded final wildcard
arm, so Tenzir can prove at compile time that all possible values are covered.
This provides a concise alternative to long <code>else if</code> chains when routing events
by field value.</p>

<h3>Uncompressed Feather output</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6045">#6045</a></small></p>
<p>The <code>write_feather</code> operator now supports <code>compression_type="uncompressed"</code>
to disable compression entirely. Previously, only <code>zstd</code> and <code>lz4</code> were
accepted:</p>
<pre><code class="language-tql">to_file "events.feather" {
  write_feather compression_type="uncompressed"
}
</code></pre>

<h3>HEC metadata and raw endpoint support in `to_splunk`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6074">#6074</a></small></p>
<p>The <code>to_splunk</code> operator gains three new options for richer HEC metadata.</p>
<p>Use <code>time=</code> to set the per-event Splunk timestamp from an expression that
evaluates to a Tenzir <code>time</code> or a non-negative epoch in seconds:</p>
<pre><code class="language-tql">from {message: "login succeeded", observed_at: 2026-04-24T08:30:00Z}
to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  time=observed_at
</code></pre>
<p>Use <code>fields=</code> to attach indexed HEC fields. The expression must evaluate to
a flat record whose values are strings or lists of strings:</p>
<pre><code class="language-tql">to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  event={message: message},
  fields={user: user, tags: tags}
</code></pre>
<p>Use <code>raw=</code> to send already-formatted text to the HEC raw endpoint
(<code>/services/collector/raw</code>). The <code>raw</code> expression must evaluate to a
<code>string</code>. Multiple events in one request are separated by newlines, and
request-level metadata such as <code>host</code>, <code>source</code>, <code>sourcetype</code>, <code>index</code>, and
<code>time</code> is sent as query parameters:</p>
<pre><code class="language-tql">to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  raw=line,
  source=source,
  sourcetype="linux_secure"
</code></pre>
<p><code>raw</code> and <code>event</code> are mutually exclusive; <code>fields</code> is not supported with
<code>raw</code>.</p>

<h3>DNS result caching in `dns_lookup`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6034">#6034</a></small></p>
<p>The <code>dns_lookup</code> operator now caches DNS results and reuses them across
lookups. Forward-lookup results gain a <code>ttl</code> field that shows the remaining
lifetime of the cached answer:</p>
<pre><code class="language-tql">from {host: "example.com"}
dns_lookup host
</code></pre>
<p>If Tenzir cannot initialize DNS resolution at all, the operator now emits an
error and stops instead of writing <code>null</code> results for every event.
Individual failed or timed-out lookups still produce <code>null</code>, as before.</p>

<h3>Keyed routing and source mode for `parallel`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5821">#5821</a></small></p>
<p>The <code>parallel</code> operator gains two enhancements:</p>
<p>The <code>jobs</code> argument is now optional and defaults to the number of available
CPU cores:</p>
<pre><code class="language-tql">subscribe "events"
parallel {
  parsed = data.parse_json()
}
</code></pre>
<p>The new <code>route_by</code> argument routes events to workers deterministically by
key. Events with the same <code>route_by</code> value always go to the same worker,
which is required for stateful subpipelines like <code>deduplicate</code> or
<code>summarize</code>:</p>
<pre><code class="language-tql">subscribe "events"
parallel route_by=src_ip {
  deduplicate src_ip, dst_ip, dst_port
}
</code></pre>
<p>Additionally, <code>parallel</code> may now be used as a source operator (without
upstream input). This spawns multiple independent instances of the
subpipeline, which is useful for running the same source pipeline with
concurrent connections.</p>

<h3>Memory-mapped reads in `from_file`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6036">#6036</a></small></p>
<p>The <code>from_file</code> operator now accepts an <code>mmap=bool</code> option that uses
memory-mapped I/O for reading local files instead of regular reads. This can
improve performance for large files:</p>
<pre><code class="language-tql">from_file "/var/log/large.json", mmap=true {
  read_json
}
</code></pre>
<p>Defaults to <code>false</code>.</p>

<h3>Parse TQL records with `read_tql`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5707">#5707</a></small></p>
<p>The new <code>read_tql</code> operator parses an incoming byte stream of TQL-formatted
records into events. Each top-level record expression becomes one event:</p>
<pre><code class="language-tql">load_file "events.tql"
read_tql
</code></pre>
<p>The input format matches the output of <code>write_tql</code>, so <code>read_tql</code> is useful
for round-tripping data through TQL notation, reading TQL-formatted files,
or processing data piped from other Tenzir pipelines.</p>

<h3>High-level filesystem and object store writers</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6053">#6053</a></small></p>
<p>Four new high-level writer operators serialize events to local filesystems
and cloud object stores with rotation, hive-style partitioning, and
per-partition unique filenames:</p>
<ul>
<li><code>to_file</code> writes to a local filesystem.</li>
<li><code>to_s3</code> writes to Amazon S3.</li>
<li><code>to_azure_blob_storage</code> writes to Azure Blob Storage.</li>
<li><code>to_google_cloud_storage</code> writes to Google Cloud Storage.</li>
</ul>
<p>Each takes a printing subpipeline, a URL with optional <code>**</code> and <code>{uuid}</code>
placeholders, and rotation parameters. The <code>**</code> placeholder expands into a
hive partitioning hierarchy based on <code>partition_by</code>, and <code>{uuid}</code> ensures
each partition gets unique destination names:</p>
<pre><code class="language-tql">subscribe "events"
to_s3 "s3://my-bucket/year=**/month=**/{uuid}.json",
  partition_by=[year, month] {
  write_ndjson
}
</code></pre>
<p>Files rotate automatically when the configured <code>max_size</code> or <code>timeout</code> is
reached, so long-running pipelines do not produce single huge objects.</p>

<h3>Send events to webhooks with `to_http`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6019">#6019</a></small></p>
<p>The new <code>to_http</code> operator sends each input event as an HTTP request to a
webhook or API endpoint. By default, it JSON-encodes the entire event as the
request body and sends it as a <code>POST</code>:</p>
<pre><code class="language-tql">subscribe "alerts"
to_http "https://example.com/webhook"
</code></pre>
<p><code>to_http</code> shares its options with <code>from_http</code> and <code>http</code>: configure
<code>method</code>, <code>body</code>, <code>encode</code>, <code>headers</code>, TLS, retries, and pagination per
request. Use <code>parallel</code> to issue multiple concurrent requests when the target
endpoint can keep up with a single pipeline.</p>
<p>This is useful for pushing alerts to webhooks, forwarding events to SIEMs,
and calling external APIs once per event.</p>

<h3>Stream pipeline output with `serve_http`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6070">#6070</a></small></p>
<p>The new <code>serve_http</code> operator starts an HTTP server and broadcasts the bytes
produced by a nested pipeline to all connected clients:</p>
<pre><code class="language-tql">from_file "example.yaml"
serve_http "0.0.0.0:8080" {
  write_ndjson
}
</code></pre>
<p>Clients connect with a <code>GET</code> request and receive a continuous HTTP response
body. Pick the wire format with the nested pipeline: <code>write_ndjson</code> for
NDJSON streams, <code>write_lines</code> for plain text, and so on. The operator does
not buffer output for clients that connect later—each client receives the
bytes produced after it connects. TLS, connection limits, and graceful
disconnect are all configurable.</p>

<h3>Live packet capture with `from_nic`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6022">#6022</a></small></p>
<p>The new <code>from_nic</code> operator captures packets from a network interface and
emits them as events directly:</p>
<pre><code class="language-tql">from_nic "eth0"
</code></pre>
<p>Without an explicit subpipeline, <code>from_nic</code> parses the captured PCAP byte
stream with <code>read_pcap</code>. Provide a subpipeline when you want to change how
the byte stream is parsed. Use the <code>filter</code> option to apply a Berkeley Packet
Filter (BPF) expression so libpcap drops unwanted traffic before parsing:</p>
<pre><code class="language-tql">from_nic "eth0", filter="tcp port 443"
</code></pre>
<p>The companion <code>read_pcap</code> and <code>write_pcap</code> operators have been refreshed:
<code>read_pcap</code> now also emits a <code>pcap.file_header</code> event when
<code>emit_file_headers=true</code>, which <code>write_pcap</code> consumes to preserve the
original timestamp precision and byte order. The <code>pcap.packet</code> schema's
<code>time.timestamp</code> field is now a top-level <code>timestamp</code> field, and <code>data</code> is
now a <code>blob</code>.</p>

<h3>Dedicated TCP source and sink operators</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5744">#5744</a>, <a href="https://github.com/tenzir/tenzir/pull/6017">#6017</a></small></p>
<p>Tenzir now has dedicated TCP source and sink operators that match the same
client/server split as the HTTP operators:</p>
<ul>
<li><code>from_tcp</code> connects to a remote TCP or TLS endpoint as a client.</li>
<li><code>accept_tcp</code> listens on a local endpoint and spawns a subpipeline per
accepted connection. Inside the subpipeline, <code>$peer.ip</code> and <code>$peer.port</code>
identify the connecting client; with <code>resolve_hostnames=true</code>,
<code>$peer.hostname</code> is also available from reverse DNS.</li>
<li><code>to_tcp</code> connects to a remote endpoint and writes serialized bytes.</li>
<li><code>serve_tcp</code> listens for incoming connections and broadcasts pipeline output
to all connected clients.</li>
</ul>
<p>Each operator takes a parsing or printing subpipeline so connection
management, framing, and serialization stay separate concerns:</p>
<pre><code class="language-tql">accept_tcp "0.0.0.0:8090" {
  read_json
}
</code></pre>
<pre><code class="language-tql">to_tcp "collector.example.com:5044" {
  write_json
}
</code></pre>
<p><code>from_tcp</code> and <code>to_tcp</code> reconnect with exponential backoff on connection
failure. All four operators support TLS via the <code>tls</code> option.</p>
<p>The legacy <code>load_tcp</code> and <code>save_tcp</code> operators are now deprecated. The
<code>tcp://</code> and <code>tcps://</code> URL schemes still dispatch to them via <code>from</code> and
<code>to</code>.</p>

<h3>Read from standard input with `from_stdin`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5731">#5731</a></small></p>
<p>The new <code>from_stdin</code> operator reads bytes from standard input through a
parsing subpipeline:</p>
<pre><code class="language-tql">from_stdin {
  read_json
}
</code></pre>
<p>This is useful when piping data into the <code>tenzir</code> executable as part of a
shell script or command chain.</p>

<h3>Synthetic event generation with `anonymize`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a></small></p>
<p>The new <code>anonymize</code> operator generates synthetic events that share the schemas
of its input. The operator first samples a configurable number of input events
to learn what schemas are present and to summarize their values, and then
replaces the input with generated events that match those schemas:</p>
<pre><code class="language-tql">subscribe "events"
anonymize count=1000
</code></pre>
<p>By default, generated values follow the aggregate statistics of the sampled
input: null rates, list lengths, numeric ranges, time and duration ranges,
boolean and enum frequencies, string and blob lengths and byte frequencies, IP
address family frequencies, and subnet prefix length frequencies. Use
<code>fully_random=true</code> to ignore those statistics and instead pick values
uniformly from each type's full range. The optional <code>seed</code> argument makes
output reproducible.</p>
<p>Use <code>anonymize</code> to share representative event traces without leaking the
underlying values.</p>

<h3>Keyed subpipeline routing with `group`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5980">#5980</a></small></p>
<p>The new <code>group</code> operator routes events with the same key through a shared
subpipeline. Inside the subpipeline, <code>$group</code> refers to the key for that
subpipeline:</p>
<pre><code class="language-tql">group tenant {
  summarize count()
}
</code></pre>
<p>The subpipeline either emits events—which are forwarded as the operator's
output—or ends with a sink, in which case <code>group</code> itself becomes a sink. Use
<code>group</code> when you need keyed routing through a stateful subpipeline, such as a
per-tenant sink or a per-session transformation. For grouped aggregations,
keep using <code>summarize</code>.</p>

<h3>Per-event subpipelines with `each`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5981">#5981</a></small></p>
<p>The new <code>each</code> operator runs a fresh subpipeline for every input event. The
event is bound to <code>$this</code> inside the subpipeline so it can parametrize the
nested logic on a per-event basis:</p>
<pre><code class="language-tql">from [
  {file: "a.json"},
  {file: "b.json"},
]
each {
  from $this.file
}
</code></pre>
<p>The subpipeline takes no input from <code>each</code>. It either emits events—which are
forwarded as the operator's output—and may also end with a sink, in which case
<code>each</code> itself becomes a sink.</p>
<p>Use <code>each</code> for per-event jobs such as a lookup, an export, or a sink whose
source depends on the incoming event. For keyed streams that should keep one
subpipeline alive per key, use <code>group</code> instead.</p>

<h3>OData pagination for from_http</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>from_http</code> operator now supports <code>paginate="odata"</code> for
<a href="https://www.oasis-open.org/standard/odata-v4-01-os/">OData</a> collection
responses such as Microsoft Graph:</p>
<pre><code class="language-tql">from_http "https://graph.microsoft.com/v1.0/users",
  headers={"ConsistencyLevel": "eventual"},
  paginate="odata" {
  read_json
}
</code></pre>
<p>This mode emits the objects from the response body's top-level <code>value</code> array
and follows top-level <code>@odata.nextLink</code> URLs until no next link is present. The
next link can be absolute or relative to the current response URL.</p>

<h3>NATS JetStream operators</h3>
<p><small>Apr 17, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Tenzir can now consume from and publish to NATS JetStream subjects with
<code>from_nats</code> and <code>to_nats</code>.</p>
<p>Use <code>from_nats</code> to receive one event per message. The raw payload appears in the
<code>message</code> blob field, and <code>metadata_field</code> attaches NATS metadata:</p>
<pre><code class="language-tql">from_nats "alerts", metadata_field=nats
parsed = string(message).parse_json()
</code></pre>
<p>Use <code>to_nats</code> to publish one message per event. By default, the operator
serializes the whole event with <code>this.print_ndjson()</code>:</p>
<pre><code class="language-tql">from {severity: "high", alert_type: "suspicious-login"}
to_nats "alerts"
</code></pre>
<p>Both operators support configurable connection settings, authentication, and
the standard Tenzir <code>tls</code> record.</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>Changes</h2>

<h3>Region derivation and endpoint logging for SQS</h3>
<p><small>May 13, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/6168">#6168</a></small></p>
<p>The <code>from_sqs</code> and <code>to_sqs</code> operators now derive the AWS region from a queue
URL when <code>aws_region</code> is not set, so passing a full URL such as
<code>https://sqs.us-west-2.amazonaws.com/123456789012/my-queue</code> works without
having to specify the region again:</p>
<pre><code class="language-tql">from_sqs "https://sqs.us-west-2.amazonaws.com/123456789012/my-queue"
</code></pre>
<p>Previously, this would fall back to the SDK default region and fail with a
SigV4 signature mismatch. Explicit <code>aws_region</code>, resolved IAM credentials, and
the SDK default still apply in that order when the URL has no region (for
example VPC endpoints, LocalStack, or an <code>AWS_ENDPOINT_URL</code> override).</p>
<p>SQS API errors and HTTP failures now also include the endpoint URL in their
log lines and diagnostic notes, which makes it easier to tell which queue
produced an error when multiple SQS pipelines run side by side.</p>

<h3>Preserve categorical order in `chart_bar`</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a></small></p>
<p>The <code>chart_bar</code> and <code>chart_pie</code> operators now preserve the incoming row order
for categorical x-axis values such as strings, IP addresses, and subnets. This
allows users to control bar order with regular TQL operators such as <code>sort</code>
before charting.</p>

<h3>Per-schema buffering and default timeout for `batch`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5878">#5878</a>, <a href="https://github.com/tenzir/tenzir/pull/5906">#5906</a></small></p>
<p>The <code>batch</code> operator now maintains separate buffers for each distinct
schema. Each buffer has independent timeout tracking and fills until reaching
the <code>limit</code>, at which point it flushes immediately. Previously, mixed-schema
streams could stall waiting for a single combined buffer to fill.</p>
<p>The <code>timeout</code> argument now defaults to <code>1min</code> instead of an infinite
duration, so buffered events are flushed at least once per minute when no new
events arrive.</p>

<h3>Add `accept_http` operator for receiving HTTP requests</h3>
<p><small>Apr 15, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>We added a new operator to accept data from incoming HTTP connections.</p>
<p>The <code>server</code> option of the <code>from_http</code> operator is now deprecated.
Going forward, it should only be used for client-mode HTTP operations,
and the new <code>accept_http</code> operator should be used for server-mode
operations.</p>

<h2>Bug Fixes</h2>

<h3>Compaction resolves package UDOs at startup</h3>
<p><small>May 20, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6210">#6210</a></small></p>
<p>The <code>compaction</code> plugin no longer fails to start with
<code>module &#x3C;package> not found</code> when a rule's <code>pipeline</code> references an
operator defined by an installed package. Previously, depending on the
order in which the node's components were initialized, the compactor's
eager rule-pipeline parse could run before the package manager had
published its operator modules to the global registry.</p>

<h3>Reduce disk I/O of time-based compaction</h3>
<p><small>May 12, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>Time-based compaction rules no longer cause the node to reprocess data that
has already been compacted in a previous run.</p>

<h3>Top-level package metadata</h3>
<p><small>May 8, 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/6149">#6149</a></small></p>
<p>Packages can now include a top-level <code>metadata</code> field for data consumed by external tools. Unknown package keys still fail validation, and the error now points users to <code>metadata</code> for non-engine package data.</p>

<h3>SentinelOne Data Lake sink support in the new executor</h3>
<p><small>Apr 24, 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/6081">#6081</a></small></p>
<p>The <code>to_sentinelone_data_lake</code> operator now works in pipelines that run on the new executor. Previously, using it there failed before the pipeline could send events.</p>
<pre><code class="language-tql">from {message: "hello"}
to_sentinelone_data_lake "https://example.com", token="TOKEN"
</code></pre>

<h3>Faster drop_null_fields on heterogeneous data</h3>
<p><small>Mar 31, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5963">#5963</a></small></p>
<p>The <code>drop_null_fields</code> operator is now much faster on heterogeneous input with many changing null patterns.</p>
]]></content>
        <published>2026-05-22T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.36.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-36-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-36-0"/>
        <updated>2026-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes int64/uint64 column merging lossless during parsing, so fields like `flow_id` that mix signed and unsigned values no longer cause unnecessary table-slice splits. It also extends ocsf::derive to handle list-valued enum fields for full bidirectional OCSF enum normalization.]]></summary>
        <content type="html"><![CDATA[<p>This release makes int64/uint64 column merging lossless during parsing, so fields like <code>flow_id</code> that mix signed and unsigned values no longer cause unnecessary table-slice splits. It also extends ocsf::derive to handle list-valued enum fields for full bidirectional OCSF enum normalization.</p>

<h2>Features</h2>

<h3>OCSF enum list derivation</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5354">#5354</a></small></p>
<p><code>ocsf::derive</code> now derives OCSF enum sibling fields for lists, not just scalar enum fields. For example, DNS answers with <code>flag_ids: [1, 3, 4]</code> now also get <code>flags: ["Authoritative Answer", "Recursion Desired", "Recursion Available"]</code>, and the reverse direction works for <code>flags</code> to <code>flag_ids</code> as well.</p>

<h2>Changes</h2>

<h3>Lossless int64/uint64 merging during parsing</h3>
<p><small>May 5, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>Parsing data that mixes <code>int64</code> and <code>uint64</code> values in the same field no longer
produces unnecessary table-slice splits, improving batching performance. Fields
like <code>flow_id</code> that are always non-negative but occasionally exceed the signed
integer limit of  <code>2^63 − 1</code> are now merged into a single <code>uint64</code> column where
possible, instead of being emitted as separate slices.</p>

<h2>Bug Fixes</h2>

<h3>Empty if branches in the new executor</h3>
<p><small>May 6, 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/6128">#6128</a></small></p>
<p>Empty <code>if</code> branches no longer crash when running pipelines with the new executor. For example, <code>if false {}</code> now behaves like an empty pass-through branch instead of triggering an internal assertion failure.</p>
]]></content>
        <published>2026-05-07T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-2"/>
        <updated>2026-05-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes two package-related bugs: startup pipelines can now reliably reference operators from static packages, and UDOs with slash-delimited string defaults (e.g. "/tmp-data/") load correctly without internal errors.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes two package-related bugs: startup pipelines can now reliably reference operators from static packages, and UDOs with slash-delimited string defaults (e.g. "/tmp-data/") load correctly without internal errors.</p>

<h2>Bug Fixes</h2>

<h3>Configured pipelines with package operators</h3>
<p><small>May 4, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Configured startup pipelines can now reference operators from static packages reliably. Previously, such pipelines could fail during node startup with <code>module &#x3C;package> not found</code>, even though the same package operator worked when run manually after startup.</p>

<h3>Slash-delimited UDO defaults</h3>
<p><small>May 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/6108">#6108</a></small></p>
<p>Package UDOs now load correctly when a typed string default looks like a TQL pattern, such as <code>default: "/tmp-data/"</code>.</p>
<p>Previously, loading such a package could abort with an unexpected internal error before any pipeline ran.</p>
]]></content>
        <published>2026-05-05T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-1"/>
        <updated>2026-04-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release restores correct retention for metrics and diagnostics in mixed-age partitions and brings back actionable TLS hints when ClickHouse connections fail due to a TLS/plaintext mismatch.]]></summary>
        <content type="html"><![CDATA[<p>This release restores correct retention for metrics and diagnostics in mixed-age partitions and brings back actionable TLS hints when ClickHouse connections fail due to a TLS/plaintext mismatch.</p>

<h2>Bug Fixes</h2>

<h3>ClickHouse TLS mismatch diagnostics</h3>
<p><small>Apr 29, 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/6098">#6098</a></small></p>
<p>ClickHouse connection errors caused by TLS/plaintext mismatches now include the TLS notes and hint again. This helps identify when <code>to_clickhouse</code> is using TLS against a plaintext ClickHouse endpoint and suggests setting <code>tls=false</code> when appropriate.</p>

<h3>Retention for mixed-age metrics partitions</h3>
<p><small>Apr 28, 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/6086">#6086</a></small></p>
<p>Default retention policies now continue deleting metrics and diagnostics as their timestamps age into the retention window, even when older and newer events share a partition.</p>
<p>Previously, a partition that still contained newer events after retention could be skipped by later retention runs, leaving those events behind after they expired.</p>
]]></content>
        <published>2026-04-30T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-0"/>
        <updated>2026-04-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes crashes in static musl builds when evaluating deeply nested generated TQL expressions.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes crashes in static musl builds when evaluating deeply nested generated TQL expressions.</p>

<h2>Bug Fixes</h2>

<h3>Static musl builds no longer crash on deep TQL expressions</h3>
<p><small>Apr 27, 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/6082">#6082</a></small></p>
<p>Static musl builds of <code>tenzir</code> no longer crash on deeply nested generated TQL
expressions.</p>
<p>This affected generated pipelines with deeply nested expressions, for example
rules or transformations that expand into long left-associated operator chains.</p>
<p>The <code>tenzir</code> binary now links with a larger default thread stack size on musl,
which brings its behavior in line with non-static builds for these pipelines.</p>
]]></content>
        <published>2026-04-29T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.34.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-34-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-34-0"/>
        <updated>2026-04-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release contains internal changes only.]]></summary>
        <content type="html"><![CDATA[<p>This release contains internal changes only.</p>
]]></content>
        <published>2026-04-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.33.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-33-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-33-0"/>
        <updated>2026-04-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes the subnet function work directly with typed and string IP addresses, which removes boilerplate in TQL pipelines. It also fixes several stability issues in where, unroll, files, context::enrich, and collection indexing.]]></summary>
        <content type="html"><![CDATA[<p>This release makes the subnet function work directly with typed and string IP addresses, which removes boilerplate in TQL pipelines. It also fixes several stability issues in where, unroll, files, context::enrich, and collection indexing.</p>

<h2>Features</h2>

<h3>IP address support in subnet</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>subnet</code> function now accepts typed IP addresses, plain IP strings, and
existing subnet values with an optional prefix length:</p>
<pre><code class="language-tql">from {source_ip: 10.10.1.124}
net = subnet(source_ip, 24)
</code></pre>
<p>This returns <code>10.10.1.0/24</code> without converting the IP address to a string first.
When you omit the prefix, IPv4 addresses become <code>/32</code> host subnets and IPv6
addresses become <code>/128</code> host subnets.</p>

<h2>Bug Fixes</h2>

<h3>Large unroll output stability</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>unroll</code> operator no longer crashes when expanding very large lists into output that exceeds Arrow's per-array capacity.</p>

<h3>Recursive files traversal of unreadable directories</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>files</code> operator now skips unreadable child directories during recursive traversal, emits a warning for each skipped directory by default, and continues listing accessible siblings. Set <code>skip_permission_denied=true</code> to ignore permission-denied paths silently: this suppresses warnings for skipped child directories and still makes an unreadable initial directory produce no events instead of an error. Non-permission filesystem errors continue to fail the pipeline.</p>

<h3>Fixed unbounded memory growth `context::enrich`</h3>
<p><small>Apr 23, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a></small></p>
<p>We fixed an issue in the <code>context::enrich</code> operator that did cause unbounded
memory growth.</p>

<h3>Crash fix for deep left-associated where expressions</h3>
<p><small>Apr 23, 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/6068">#6068</a></small></p>
<p>Tenzir no longer segfaults on some very deep left-associated boolean
expressions in <code>where</code> clauses due to source-location handling.</p>

<h3>Unsigned integer indexing in TQL</h3>
<p><small>Apr 22, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Both list and record indexing in TQL now work with signed and unsigned integer indices.
This also applies to record field-position indexing and to the <code>get</code> function for records and lists.</p>
]]></content>
        <published>2026-04-24T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.32.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-32-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-32-1"/>
        <updated>2026-04-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release fixes two correctness issues in stateful pipeline execution. Partition rebuilds now complete after writing replacement partitions, and periodic summarize output remains deterministic for delayed or sparse streams.]]></summary>
        <content type="html"><![CDATA[<p>This patch release fixes two correctness issues in stateful pipeline execution. Partition rebuilds now complete after writing replacement partitions, and periodic summarize output remains deterministic for delayed or sparse streams.</p>

<h2>Bug Fixes</h2>

<h3>Partition rebuild completion</h3>
<p><small>Apr 20, 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/6059">#6059</a></small></p>
<p>Partition rebuilds now finish after persisting rebuilt partitions. Previously, rebuild jobs could remain stuck indefinitely even though the replacement partitions were written successfully.</p>

<h3>Deterministic periodic summarize output</h3>
<p><small>Apr 16, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>summarize</code> operator now starts <code>frequency</code>-based emission with the first
input event and emits overdue periodic results before later events are
aggregated. This makes periodic output deterministic in <code>reset</code>,
<code>cumulative</code>, and <code>update</code> modes for delayed or sparse streams.</p>
<p>For example:</p>
<pre><code class="language-tql">from {ts: 0ms.from_epoch(), x: 1},
     {ts: 90ms.from_epoch(), x: 1},
     {ts: 360ms.from_epoch(), x: 1}
delay ts
summarize count=count(), options={frequency: 300ms, mode: "cumulative"}
</code></pre>
<p>The first periodic result now consistently reports a count of <code>2</code> before the
third event arrives.</p>
]]></content>
        <published>2026-04-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.32.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-32-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-32-0"/>
        <updated>2026-04-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir nodes now honor standard HTTP proxy environment variables when connecting to the Tenzir Platform, and hash functions produce correct checksums for binary values.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir nodes now honor standard HTTP proxy environment variables when connecting to the Tenzir Platform, and hash functions produce correct checksums for binary values.</p>

<h2>Features</h2>

<h3>Platform websocket proxy support</h3>
<p><small>Apr 16, 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/6039">#6039</a></small></p>
<p>Tenzir nodes now honor standard HTTP proxy environment variables when connecting to Tenzir Platform:</p>
<pre><code class="language-sh">HTTPS_PROXY=http://proxy.example:3128 tenzir-node
</code></pre>
<p>Use <code>NO_PROXY</code> to bypass the proxy for selected hosts. This helps deployments where outbound connections to the Platform websocket gateway must go through an HTTP proxy.</p>

<h2>Bug Fixes</h2>

<h3>Raw-byte hashing for binary values</h3>
<p><small>Apr 16, 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/6022">#6022</a></small></p>
<p>The <code>hash_*</code> functions now hash <code>blob</code> values by their raw bytes. This makes checksums computed from binary data match external tools such as <code>md5sum</code> and <code>sha256sum</code>.</p>
<p>For example:</p>
<pre><code class="language-tql">from_file "trace.pcap" {
  read_all binary=true
}
md5 = data.hash_md5()
</code></pre>
<p>This is useful for verifying file contents and round-tripping binary formats without leaving TQL.</p>
]]></content>
        <published>2026-04-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.31.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-31-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-31-0"/>
        <updated>2026-04-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir now unifies live and retrospective context matching with the new `context::lookup` operator, and it adds pipeline names to diagnostics and metrics for easier operational correlation. This release also improves export reliability under load and fixes Azure transport errors, HTTP Host headers for non-standard ports, and rebuilt-partition export correctness.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir now unifies live and retrospective context matching with the new <code>context::lookup</code> operator, and it adds pipeline names to diagnostics and metrics for easier operational correlation. This release also improves export reliability under load and fixes Azure transport errors, HTTP Host headers for non-standard ports, and rebuilt-partition export correctness.</p>

<h2>Features</h2>

<h3>Unified context lookups with `context::lookup` operator</h3>
<p><small>Apr 1, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5964">#5964</a></small></p>
<p>The <code>context::lookup</code> operator enables unified matching of events against contexts
by combining live and retrospective filtering in a single operation.</p>
<p>The operator automatically translates context updates into historical queries
while simultaneously filtering all newly ingested data against any context updates.</p>
<p>This provides:</p>
<ul>
<li><strong>Live matching</strong>: Filter incoming events through a context with <code>live=true</code></li>
<li><strong>Retrospective matching</strong>: Apply context updates to historical data with <code>retro=true</code></li>
<li><strong>Unified operation</strong>: Use both together (default) to match all events—new and historical</li>
</ul>
<p>Example usage:</p>
<pre><code class="language-tql">context::lookup "feodo", field=src_ip
where @name == "suricata.flow"
</code></pre>

<h3>Include pipeline names in diagnostics and metrics</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5959">#5959</a></small></p>
<p>The <code>metrics</code> and <code>diagnostics</code> operators now include a <code>pipeline_name</code> field.</p>
<p>Previously, output from these operators only identified the source pipeline by its ID.
Now the human-readable name is available too, making it straightforward to filter
or group results by pipeline name without needing to look up IDs separately.</p>
<p>Please keep in mind that pipeline names are not unique.</p>

<h2>Bug Fixes</h2>

<h3>Fix crash on Azure SSL/transport errors during read and write operations</h3>
<p><small>Apr 8, 2026 · <a href="https://github.com/claude">@claude</a></small></p>
<p>Bumped Apache Arrow from 23.0.0 to 23.0.1, which includes an upstream fix
for unhandled <code>Azure::Core::Http::TransportException</code> in Arrow's
<code>AzureFileSystem</code> methods. Previously, transport-level errors (e.g., SSL
certificate failures) could crash the node during file listing, reading, or
writing. Additionally, the direct Azure SDK calls in the blob deletion code
paths now catch <code>Azure::Core::RequestFailedException</code> (the common base of
both <code>StorageException</code> and <code>TransportException</code>) instead of listing
specific exception types.</p>

<h3>Reliable export for null rows in rebuilt partitions</h3>
<p><small>Apr 7, 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/5988">#5988</a></small></p>
<p>The <code>export</code> operator no longer emits partially populated events from rebuilt partitions when a row is null at the record level. Previously, some events could appear with most fields set to <code>null</code> while a few values, such as <code>event_type</code> or interface fields, were still present.</p>
<p>This makes exports from rebuilt data more reliable when investigating sparse or malformed-looking events.</p>

<h3>Fix HTTP Host header missing port for non-standard ports</h3>
<p><small>Mar 31, 2026</small></p>
<p>The <code>from_http</code> and <code>http</code> operators now include the port in the <code>Host</code> header
when the URL uses a non-standard port. Previously, the port was omitted, which
caused requests to fail with HTTP 403 when the server validates the <code>Host</code>
header against the full authority, such as for pre-signed URL signature
verification.</p>

<h3>Reliable recent exports during partition flushes</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>export</code> command no longer fails or misses recent events when a node is flushing active partitions to disk under heavy load. Recent exports now keep the in-memory partitions they depend on alive until the snapshot completes, which preserves correctness for concurrent import and export workloads.</p>
]]></content>
        <published>2026-04-14T00:00:00.000Z</published>
    </entry>
    <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>
</feed>