A pcomm= field that secretly doubles old LogQL comm= filters
Notes. Measured on one Loki-backed pipeline after a process-exec logger added a parent-command field. Single live-window measurements; the double-count is exact and reproducible. Corrections welcome.
At 10,000 feet
Setting: a Loki + LogQL pipeline whose detection rules match process-exec
log lines by substring, e.g. |~ "comm=runc ".
Problem: a new parent-command field pcomm= shipped, and since comm= is
a substring of pcomm=, every pre-existing bare comm= filter silently
doubled its match set — no rule was edited.
What this note establishes: the exact double-count on a live window; the
fix is a word boundary (\b), which RE2 (Loki’s regex engine) supports.
Takeaway: a bare key= substring filter is unsafe once any other field
name ends in that string — anchor key/value matchers with \b (or an explicit
line start).
The measurement (measured)
Same live 10-minute window:
| Filter | Lines matched |
|---|---|
|~ "comm=runc " (bare substring) |
1002 |
\bcomm=runc (word-boundary anchored) |
502 |
\bpcomm=runc (the parent field) |
1005 |
The bare 1002 is essentially the real 502 plus parent-field matches it was
never meant to see (the parent field roughly mirrors the command field here);
\b recovers the intended 502.
The fix, and why this bites
Every key=value matcher in the rule set was regenerated with the boundary.
The same hazard hits any prefix collision (pid= inside ppid=), invisibly —
rules keep “working” while counting twice and tripping count-based thresholds.
Treat log record format as an interface: audit substring filters whenever a
field name is added.
Prior art, and what is new
The general pitfall is the Scunthorpe problem (a substring matching inside
a larger token); credit goes there. New: this specific auditd/exec comm= vs
pcomm= double-count in LogQL, measured, with the word-boundary fix — no
public documentation of it was found.
Licensed under the site footer’s CC BY 4.0. If this saved you a silent double-count, the optional thanks link in the footer is appreciated, no obligation.
Validation (reproduced on Loki 3.4.1, 2026-08-31)
Throwaway single-binary Loki 3.4.1 in Docker, 1,000 synthetic auditd-style
lines: 300 with comm=runc , 200 with pcomm=runc (their own comm is
containerd-shim), 500 noise. Full-window query_range:
| Filter | Matches |
|---|---|
\|~ comm=runc `` (bare) |
500 (inflated: comm + pcomm lines) |
\|~ \bcomm=runc `` |
300 (comm lines only) |
\|~ \bpcomm=runc `` |
200 (pcomm lines only) |
Verdict: reproduced. 500 = 300 + 200 — bare comm= matches pcomm= lines
as a substring — and RE2’s \b works in Loki line filters (p→c is not a
word boundary).