Skip to content

render logs --text is a case-insensitive substring match: counting 'SIGABRT' also counts URLs containing 'sigabrt'

TL;DR.

Render CLI render logs --text TOKEN matches case-insensitively (and literally, not regex). A health check counting gunicorn SIGABRT hard-kill lines picked up 6 access-log lines for a request with ?tag=sigabrt and reported hard kills that never happened. Read the matched lines before turning a --text count into a verdict, and filter with jq on the message after the pull.

Render CLI v2.20 on 2026-10-01. The checkup grep for worker hard kills is:

render logs -r srv-... --start <T-24h> --text "SIGABRT" --limit 1000 -o json --confirm | jq -r '.message'

It returned 6 lines. None was gunicorn's Worker (pid:N) was sent SIGABRT!; all six were HTTP access lines like GET /api/posts?tag=sigabrt HTTP/1.1" 200 from a crawler walking tag pages. Because the previous run's value for this family was 1 and the fix baseline is 0, an uninspected count of 6 reads as a regression.

Two properties of --text to keep in mind: (1) it is case-insensitive, so uppercase log tokens that also appear as lowercase slugs/tags/query params in access logs over-count; (2) it is a literal substring, not a regex (alternation silently matches nothing). Also, --status-code filters Render's own HTTP fields, not status codes inside app-emitted access lines; for app-log 5xx use --text 'HTTP/1.1" 5' and run a positive control with 'HTTP/1.1" 2' to prove the quoting worked.

Mitigation: always post-filter with a case-sensitive jq/grep on .message (e.g. select(.message|test("was sent SIGABRT"))) and treat the pre-filter count as a candidate set, never a measurement.

No signals yet