# How to Use Experimental Exclude Patterns in osv-scanner Scans

> Learn how to use experimental exclude patterns in osv-scanner scans with the --experimental-exclude flag. Skip directories using exact matches, globs, or regex for precise vulnerability scanning.

- Repository: [Google/osv-scanner](https://github.com/google/osv-scanner)
- Tags: how-to-guide
- Published: 2026-04-25

---

**Use the `--experimental-exclude` flag with `osv-scanner scan source` to skip directories using exact matches, glob patterns (prefix with `g:`), or regular expressions (prefix with `r:`).**

The `osv-scanner` tool from Google provides an experimental mechanism to filter directories during vulnerability scans. This feature parses exclusion rules from the command line, compiles them into optimized matchers, and injects them into the underlying Scalibr scanning engine. Understanding how these **experimental exclude patterns** are processed helps you optimize scan times by eliminating irrelevant paths like test suites or dependency caches.

## How the Experimental Exclude Flag Works

The implementation spans multiple packages, converting CLI arguments into compiled patterns that the file system walker uses to prune directories.

### CLI Flag Definition

The flag is declared in [`cmd/osv-scanner/scan/source/command.go`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/scan/source/command.go) as a `StringSliceFlag`, allowing multiple exclusion rules in a single scan:

```go
&cli.StringSliceFlag{
    Name:  "experimental-exclude",
    Usage: "exclude directory paths during scanning; use g:pattern for glob, r:pattern for regex, or just dirname for exact match (can be repeated)",
},

```

The parsed values are stored in `experimentalScannerActions.ExcludePatterns` before being passed to the scanning logic.

### Pattern Parsing and Compilation

In [`pkg/osvscanner/exclude.go`](https://github.com/google/osv-scanner/blob/main/pkg/osvscanner/exclude.go), the `parseExcludePatterns` function processes each argument. It uses `parseExcludeArg` to split entries into a type prefix and raw pattern:

- **Exact match** – no prefix (stored in `dirsToSkip`)
- **Glob** – `g:` prefix (compiled using `github.com/gobwas/glob`)
- **Regex** – `r:` prefix (compiled into a cached `regexp.Regexp`)

The compiled results are held in the `excludePatterns` struct:

```go
type excludePatterns struct {
    dirsToSkip   []string
    globPattern  glob.Glob
    regexPattern *regexp.Regexp
}

```

Glob patterns are merged internally with `{p1,p2,…}` syntax, while regex patterns use alternation `(p1|p2|…)` for efficiency.

### Scanner Integration

The `DoScan` function in [`pkg/osvscanner/scan.go`](https://github.com/google/osv-scanner/blob/main/pkg/osvscanner/scan.go) injects these patterns into the Scalibr configuration:

```go
DirsToSkip:   excludePatterns.dirsToSkip,
SkipDirRegex: excludePatterns.regexPattern,
SkipDirGlob:  excludePatterns.globPattern,

```

Scalibr’s directory walker checks each path against these three matchers during the file system traversal. Any match causes the walker to skip that directory and its children silently.

## Pattern Syntax and Types

`osv-scanner` supports three distinct pattern types, differentiated by their prefix.

### Exact Directory Names

Provide the directory name without any prefix to exclude specific folder names regardless of their location in the tree. These are collected in the `dirsToSkip` slice and matched literally against path components.

```bash
osv-scanner scan source -r \
    --experimental-exclude=test \
    --experimental-exclude=docs \
    ./my/project

```

### Glob Patterns

Prefix the pattern with `g:` to use glob syntax. This supports wildcards like `*` (single level) and `**` (recursive) to match directories at any depth.

```bash
osv-scanner scan source -r \
    --experimental-exclude="g:**/vendor/**" \
    ./my/project

```

The glob compiler merges multiple patterns for efficient matching.

### Regular Expressions

Prefix with `r:` to supply a RE2-compatible regular expression. This is useful for complex exclusion rules, such as matching directories ending with specific suffixes.

```bash
osv-scanner scan source -r \
    --experimental-exclude="r:\\.cache$" \
    ./my/project

```

Malformed regex patterns return an error during the compilation phase.

## Command Line Examples

You can combine multiple pattern types in a single scan by repeating the flag:

```bash

# Mixed exclusion: exact name, glob, and regex

osv-scanner scan source -r \
    --experimental-exclude=nested \
    --experimental-exclude="g:**/test/**" \
    --experimental-exclude="r:^tmp_" \
    ./my/project

```

All exclusions are documented in [`docs/scan-source.md`](https://github.com/google/osv-scanner/blob/main/docs/scan-source.md) along with usage notes.

## Programmatic Usage

When integrating `osv-scanner` into Go applications, populate the `ExperimentalScannerActions` struct:

```go
package main

import (
    "github.com/google/osv-scanner/v2/pkg/osvscanner"
    "github.com/google/osv-scanner/v2/internal/helper"
)

func main() {
    exp := osvscanner.ExperimentalScannerActions{
        ExcludePatterns: []string{
            "vendor",                 // exact match
            "g:**/test/**",           // glob
            "r:\\.cache$",            // regex
        },
    }

    scan := helper.CommonScannerActions{
        Recursive: true,
        DirectoryPaths: []string{"./my/project"},
        ExperimentalScannerActions: exp,
    }

    results, err := osvscanner.DoScan(scan)
    if err != nil && err != osvscanner.ErrNoPackagesFound {
        panic(err)
    }
    // Process results...
}

```

The `ExcludePatterns` slice flows through the same parsing pipeline used by the CLI, as defined in [`pkg/osvscanner/exclude.go`](https://github.com/google/osv-scanner/blob/main/pkg/osvscanner/exclude.go).

## Summary

- The `--experimental-exclude` flag enables directory filtering during `osv-scanner scan source` operations.
- Patterns support three modes: exact names (no prefix), globs (`g:` prefix), and regexes (`r:` prefix).
- Implementation resides in [`cmd/osv-scanner/scan/source/command.go`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/scan/source/command.go) (CLI), [`pkg/osvscanner/exclude.go`](https://github.com/google/osv-scanner/blob/main/pkg/osvscanner/exclude.go) (parsing), and [`pkg/osvscanner/scan.go`](https://github.com/google/osv-scanner/blob/main/pkg/osvscanner/scan.go) (injection).
- Glob patterns use the `github.com/gobwas/glob` library; regex patterns use Go’s standard `regexp` package.
- The feature is experimental and tested in [`cmd/osv-scanner/scan/source/command_test.go`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/scan/source/command_test.go).

## Frequently Asked Questions

### Is the exclude pattern feature stable?

No, this is an **experimental** feature. The `--experimental-exclude` flag name, syntax, and behavior may change in future releases of `osv-scanner` as the implementation matures. Monitor the project’s changelog for updates.

### Can I use multiple exclude patterns in one command?

Yes. The flag accepts multiple values. You can repeat `--experimental-exclude` with different patterns, mixing exact names, globs, and regexes in the same scan invocation. The scanner applies all patterns cumulatively.

### What regex engine does osv-scanner use?

The tool uses Go’s standard `regexp` package (RE2 syntax) for regex patterns. Patterns prefixed with `r:` must be valid RE2 expressions; otherwise, `parseExcludePatterns` returns a compilation error before scanning begins.

### How do I exclude directories nested at any depth?

Use a **glob pattern** with the `**` wildcard. Prefix your pattern with `g:` and use syntax like `**/vendor/**` to match and exclude `vendor` directories regardless of their depth in the project hierarchy.