Bundled ugrep OOMs the host: -E with two bounded {0,N} intervals explodes DFA construction to multiple GB

Open 💬 3 comments Opened Jun 10, 2026 by interkelstar

What happened

Claude Code's bundled ugrep (the CLI re-execs its own binary as ugrep, argv0=ugrep) allocates unbounded memory during regex compilation when run with -E (POSIX extended regex) on a pattern containing two bounded .{0,N} intervals. It reaches multiple GB of RSS before scanning any input and is OOM-killed (or SIGSEGVs under an address-space limit).

On a 12 GB Linux host this repeatedly killed whole Claude Code sessions. Captured processes reached 4.3 GB and 8.0 GB RSS; the kernel OOM-killer took down the session each time. The triggering process was a real Grep/search invocation of the form:

ugrep -E -o '.{0,40}(session-corpus|short-term-recall|...).{0,30}' <a 74 KB file>

The 74 KB file is irrelevant — the process dies in DFA construction, before reading data.

Minimal reproduction (verified)

# point a name "ugrep" at the bundled binary (adjust the version string)
ln -sf ~/.local/share/claude/versions/2.1.170 /tmp/ugrep
printf 'x\n' > /tmp/f

# BAD: RSS climbs to the 2.5 GB cap, then SIGSEGV (exit 139), zero output
( ulimit -v 2500000; /tmp/ugrep -E -o '.{0,40}abc.{0,30}' /tmp/f )

# GOOD: identical pattern under PCRE2 -> ~8 MB, instant, exits cleanly
( ulimit -v 2500000; /tmp/ugrep -P -o '.{0,40}abc.{0,30}' /tmp/f )

Narrowing:

  • Two bounded intervals are required: .{0,40}abc.{0,30} explodes; a single .{0,80}abc is fine.
  • -o and alternation are not required.
  • Independent of input size/content (a 1-byte file still SIGSEGVs) — confirming the blow-up is in regex/DFA compilation, not scanning.
  • Measured: -E peaks at the imposed cap (~2.37 GB) and SIGSEGVs after ~15–27 s of CPU; -P, -G, and -F all finish instantly at ~8 MB.

Expected

Bounded memory: compile the ERE efficiently, or cap memory and exit with an error.

Actual

Multi-GB allocation during regex compilation → OOM-kill / SIGSEGV. On a real host this silently exhausts RAM and kills the Claude Code session running the search.

Environment

  • Claude Code 2.1.170 (native install), bundled ugrep, Node v24 SEA
  • Linux (Fedora 44, x86-64), 12 GB RAM

Suggested fix

Use -P (PCRE2) for Grep patterns containing .{0,N} intervals, and/or bound ugrep's memory, and/or guard the Grep tool's pattern construction against multi-interval POSIX-ERE patterns.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗