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
- Remove the banned byte literal from the pattern (drop the \x00 / \n segment).
- 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).
- 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
- Avoid embedding the banned byte (often NUL) as a literal in patterns.
- Use negated/broad classes ([^\x00] or [\x00a]) which are permitted.
- If you must match the byte, reconfigure the builder to not ban it.
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
- found invalid UTF-8 in pattern at byte offset {}: {} (disabl
- line terminators must be ASCII, but {byte:?} is not
- the literal {:?} is not allowed in a regex
AI-assisted analysis of BurntSushi/ripgrep@3fce3b5bb0 (2026-08-06).
Data as JSON: /data/errors/5d7ddfc9910d4c46.json.
Report an issue: GitHub.