BurntSushi/ripgrep · error · Error

pattern contains {byte:?} but it is impossible to match

Error message

pattern contains {byte:?} but it is impossible to match

What it means

ban::check walks the regex HIR and returns ErrorKind::Banned(byte) when a sub-expression is forced to match a specific ASCII byte that has been banned (commonly NUL, 0x00, to keep searches line-oriented and avoid binary-data matches). The Display says the pattern contains that byte but it is impossible to match under the configured constraints. Banning only triggers for single-range classes or literals, not broad classes like [^\x00].

Source

Thrown at crates/regex/src/ban.rs:11

use regex_syntax::hir::{
    self, ClassBytesRange, ClassUnicodeRange, Hir, HirKind,
};

use crate::error::{Error, ErrorKind};

/// Returns an error when a sub-expression in `expr` must match `byte`.
pub(crate) fn check(expr: &Hir, byte: u8) -> Result<(), Error> {
    assert!(byte.is_ascii(), "ban byte must be ASCII");
    let ch = char::from(byte);
    let invalid = || Err(Error::new(ErrorKind::Banned(byte)));
    match *expr.kind() {
        HirKind::Empty => {}
        HirKind::Literal(hir::Literal(ref lit)) => {
            if lit.iter().find(|&&b| b == byte).is_some() {
                return invalid();
            }
        }
        HirKind::Class(hir::Class::Unicode(ref cls)) => {
            if cls.ranges().iter().map(|r| r.len()).sum::<usize>() == 1 {
                let contains =
                    |r: &&ClassUnicodeRange| r.start() <= ch && ch <= r.end();
                if cls.ranges().iter().find(contains).is_some() {
                    return invalid();
                }
            }
        }
        HirKind::Class(hir::Class::Bytes(ref cls)) => {
            if cls.ranges().iter().map(|r| r.len()).sum::<usize>() == 1 {

View on GitHub (pinned to 3fce3b5bb0)

Solutions

  1. Remove the banned byte literal from the pattern (drop the \x00 / \n segment).
  2. Use a negated or broader class so the byte is not compelled to match (e.g. [^\x00] is allowed; [\x00a] is also allowed because it is not a singleton).
  3. Reconfigure the regex builder to not ban that byte if matching it is genuinely required.

Example fix

// before
// pattern "\x00" with NUL banned -> Banned(0)

// after
// pattern "[^\x00]" matches anything except NUL and is permitted
Defensive patterns

Strategy: validation

Validate before calling

fn pattern_bans_byte(pat: &str, banned: u8) -> bool {
    // crude check: literal \xNN equal to banned byte appears as a singleton
    let needle = format!("\\x{:02X}", banned);
    pat.contains(&needle)
}

Try / catch

if let Err(e) = regex::Regex::new(pat) {
    eprintln!("{e}"); // may be a banned byte
}

Prevention

When it happens

Trigger: Building a regex with a configured banned byte (e.g. NUL) where the pattern contains a literal \x00, a literal '\n' when \n is banned, or a singleton class like [\x00] — i.e. the regex is compelled to match the banned byte.

Common situations: ripgrep banning NUL so that patterns do not match inside binary data; a pattern like \x00 used to find NUL bytes that the searcher has been configured to forbid; copying a pattern from a context that allowed NUL into one that bans it.

Related errors


AI-assisted analysis of BurntSushi/ripgrep@3fce3b5bb0 (2026-08-06). Data as JSON: /data/errors/5d7ddfc9910d4c46.json. Report an issue: GitHub.