gitleaks/gitleaks
Debugging
Tactics for tracking down problems in scans and tests.
Verbose output
Two flags help you understand what a scan is doing:
-v/--verbose— print every finding to stdout in a human-friendly format (with color, unless--no-color). Implementation inprintFinding(detect/utils.go).-l trace/--log-level trace— emit detailed structured logs for every fragment, allowlist hit, low-entropy skip, and decoded segment.
trace is loud but invaluable when you suspect a finding is being silently filtered. Examples of trace messages emitted from Detector.detectRule:
skipping file: matches config or baseline pathskipping file: global allowlistskipping file: rule allowlistskipping finding: low entropyskipping finding: 'gitleaks:allow' signatureskipping finding: global allowlistskipping finding: rule allowlist
Diagnostics: pprof and trace
cmd/diagnostics.go wires --diagnostics into the scan lifecycle. The flag accepts a comma-separated list of cpu, mem, trace, or the single value http (which starts a net/http/pprof server on localhost:6060).
# Write cpu.pprof, mem.pprof, trace.out to ./profile-out
gitleaks git . --diagnostics=cpu,mem,trace --diagnostics-dir=./profile-out
# Or expose the standard pprof server
gitleaks git . --diagnostics=http
# Then in another shell:
go tool pprof http://localhost:6060/debug/pprof/profileProfiling output lands wherever --diagnostics-dir points (defaults to cwd). The Makefile target make profile builds the binary and runs scripts/profile.sh for a one-shot CPU profile.
Slow-fragment warnings
The constant SlowWarningThreshold in detect/detect.go defaults to 5 seconds. When --log-level=debug (or trace) is on, any fragment that takes longer than 5s logs a Taking longer than 5s to inspect fragment message including the path. Use this to find pathological inputs and consider tightening allowlists.
Common pitfalls
| Symptom | Likely cause |
|---|---|
| "no leaks found" but you expected one | The fragment doesn't include any rule keyword. The keyword pre-filter (prefilter in detect.go) skips the rule entirely. Check that your rule's Keywords actually appear in the input. |
Finding shows up in dir but not git |
git log -p only sees additions. If the secret was added long ago and never modified, --log-opts="--all" or scanning the working tree as a directory may help. |
| Rule matches in tests but not in real repos | Path filters or the global allowlist suppressing the file. Run with -l trace to see "skipping file" messages. |
| Findings missed inside zip/tar files | --max-archive-depth defaults to 0 (disabled). Set it to a depth ≥ 1. |
| Secrets inside base64 are missed | --max-decode-depth defaults to 0 (disabled when set on the command line, though the persistent flag's default is 5 — check cmd/root.go for the active default). |
gitleaks:allow line still triggers |
--ignore-gitleaks-allow is set. |
Inspecting line/column resolution
When a finding has the wrong line number, the suspect is usually location() (detect/location.go) or the newLineRegexp index built in DetectContext. Most issues with line numbers come from edge cases at the boundary of a fragment (e.g., a multi-line secret split across two scan chunks). The relevant tests are in detect/location_test.go.
Debugging the codec
The decoder writes one Debug log line per encoded segment found:
segment found: original=<startEnd> pos=<startEnd>: <encoded> -> <decoded>If you suspect a secret hidden in nested base64-of-base64, run with -l debug --max-decode-depth=10 and watch for these lines. Each pass increments depth in Detector.DetectContext's scan loop; the loop terminates when no new encoded segments are found or depth exceeds the cap.
Library mode
If you're embedding Gitleaks programmatically, the public surface is:
detector, _ := detect.NewDetectorDefaultConfig()
findings := detector.DetectString("aws_secret_access_key=AKIAIOSFODNN7EXAMPLE")NewDetectorDefaultConfig (detect/detect.go) reads the embedded config.DefaultConfig and builds a ready-to-use detector. To customize the config, instantiate a config.ViperConfig, call Translate, and pass it to NewDetectorContext.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.