How to Debug Why ripgrep Is Skipping Certain Files: A Complete Guide to Ignore Logic
Use the --debug flag to reveal exactly why ripgrep ignores specific files, showing real-time matches against ignore rules, size limits, binary detection, and permission errors.
When ripgrep (rg) silently excludes files from search results, it is applying a filter defined in the BurntSushi/ripgrep source code that you may not expect. Learning how to debug why ripgrep is skipping certain files requires understanding the internal walker logic and leveraging the diagnostic logging built into the tool.
Enable Debug Logging with the --debug Flag
The primary mechanism for diagnosing skipped files is the --debug flag, defined in [crates/core/flags/defs.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/flags/defs.rs#L154-L180). When invoked, this flag activates LoggingMode::Debug, which captures internal filtering decisions from the ignore walker and routes explanatory messages to stderr.
If ripgrep finishes without searching any files, the CLI explicitly prompts you to use this flag. The user-visible hint is implemented in [crates/core/main.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/main.rs#L14-L22):
fn eprint_nothing_searched() {
err_message!(
"No files were searched, which means ripgrep probably \
applied a filter you didn't expect.\n\
Running with --debug will show why files are being skipped."
);
}
To start debugging, run:
rg --debug "your_pattern" .
Understanding the Skip Logic in the Source Code
The decision to skip a file occurs in several distinct stages within the ignore and core crates. Each stage emits a specific debug message when the --debug flag is active.
Ignore Rules and Pattern Matching
The skip_entry function in crates/ignore/src/walk.rs evaluates every path against compiled ignore matchers. If a rule from .gitignore, .ignore, or --ignore-file matches, the walker returns immediately without searching the file.
The debug output appears as:
debug: ignored path ./target/debug/main.rs (matched .gitignore rule)
File Size Limitations
When --max-filesize is set, the walker invokes skip_filesize to compare the file’s metadata against the limit. Files exceeding the threshold are skipped before any content is read.
The corresponding debug message is:
debug: skipping file ./logs/huge.log (size > max-filesize)
Binary File Detection
Binary detection logic resides in [crates/core/search.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/search.rs#L135-L140), where BinaryDetection::quit causes the searcher to abort immediately upon detecting binary content. This prevents printing garbage to the terminal.
You will see:
debug: binary file ./assets/image.png (skipping)
Hidden Files and Directories
By default, ripgrep treats hidden files (those starting with a dot) as ignorable. This default type pattern is defined in [crates/ignore/src/default_types.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/ignore/src/default_types.rs#L11-L30). Unless you provide the --hidden flag, these entries are filtered out during the walk.
The debug log shows:
debug: ignoring hidden file ./.config/old.toml
Permission Errors
When the walker encounters a directory it cannot read, the error propagates through [crates/ignore/src/dir.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/ignore/src/dir.rs#L428-L440) and is logged as a skip reason rather than a hard failure.
The output looks like:
debug: cannot read directory ./secret (permission denied)
Advanced Debugging with --trace
For exhaustive detail about the directory traversal, use the --trace flag. This implies --debug and additionally prints low-level state transitions, glob matching steps, and cache operations from the walk builder.
rg --trace "pattern" ./src
Trace output includes entries such as:
trace: entering directory ./src/components
trace: applying ignore file ./src/.gitignore
trace: glob '*.test.js' matches ./src/components/Button.test.js
debug: ignored path ./src/components/Button.test.js (matched .gitignore rule)
Practical Code Examples
Identify the Specific Ignore Rule
# Shows which pattern in which file caused the skip
rg --debug --stats "fn main" . 2>&1 | grep "ignored path"
Verify File Size Constraints
# Debug why large files are missing from results
rg --debug --max-filesize 1M "TODO" ./projects
Look for the line:
debug: skipping file ./projects/big_data.csv (size > max-filesize)
Force Search of Binary Files
# Override binary detection while still viewing debug info
rg --debug --binary "magic_bytes" ./firmware
Summary
- Use
--debugto expose the exact reason ripgrep skips any file, powered by the logging infrastructure in [crates/core/flags/defs.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/flags/defs.rs#L154-L180). - Check ignore logic in [
crates/ignore/src/walk.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/ignore/src/walk.rs#L1057-L1080) to understand.gitignoreand.ignorematching. - Review size limits via the
skip_filesizecheck when using--max-filesize. - Recognize binary detection triggers in [
crates/core/search.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/search.rs#L135-L140) and override with--binaryor--text. - Account for hidden files defined in [
crates/ignore/src/default_types.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/ignore/src/default_types.rs#L11-L30) by adding--hidden. - Leverage
--tracefor walker-level diagnostics when--debugdoes not provide sufficient detail.
Frequently Asked Questions
How do I see exactly which ignore rule is skipping my file?
Run ripgrep with the --debug flag and inspect stderr for lines containing matched .gitignore rule or similar patterns. The output originates from the ignore matcher in [crates/ignore/src/walk.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/ignore/src/walk.rs#L1057-L1080), which identifies the specific pattern and source file responsible for the exclusion.
Why does ripgrep skip large files even when they match my pattern?
The --max-filesize parameter triggers a check in the skip_filesize function within the walker. If a file exceeds this byte limit, ripgrep skips it to prevent memory exhaustion. Increase the limit with --max-filesize 50M or remove the constraint entirely to search larger files.
Can I force ripgrep to search files it detects as binary?
Yes. Use the --binary flag to treat binary files as text, or use --text to force searching while still identifying binary content. This overrides the BinaryDetection::quit behavior defined in [crates/core/search.rs](https://github.com/BurntSushi/ripgrep/blob/master/crates/core/search.rs#L135-L140), allowing you to search compiled objects, images, or archives.
What is the difference between --debug and --trace?
The --debug flag enables high-level skip reasons and operational messages, while --trace implies --debug and adds low-level trace data from the directory walker. --trace reveals glob matching steps, cache hits, and state transitions, providing exhaustive detail useful for filing bug reports or debugging complex ignore hierarchies.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →