GitLab CI Error Guide: 'secret_detection: no matching files' Empty Scan
Fix GitLab's secret_detection job finding 'no matching files. Skipping...': correct git history depth, scan paths, and template variables so the scanner runs.
- #gitlab-cicd
- #troubleshooting
- #errors
- #security
Exact Error Message
The secret_detection job completes “green” but never actually scans anything:
[INFO] GitLab secret detection
[INFO] Detecting project ...
[WARN] git log --all is empty, expanding scan to working tree
[INFO] No matching files. Skipping detect-secrets...
[INFO] Secret detection scan completed in 0.4s. 0 findings.
Job succeeded
Variations include no matching input files and skipping secrets detection: no commits to scan. The job exits 0, so pipelines pass — but no secret scanning happened, which is a silent security gap rather than a hard failure.
What the Error Means
GitLab’s secret detection (a Gitleaks-based analyzer pulled in by the Security/Secret-Detection.gitlab-ci.yml template) scans either the git history of the commits in your pipeline or the working tree. “No matching files” / “no commits to scan” means the analyzer was handed an empty set: the shallow clone gave it no commit range, the scan path matched nothing, or a template variable disabled the file set it would have scanned.
The danger is that this is a skip, not an error. The job is green, so it is easy to believe scanning is active when it is doing nothing.
Common Causes
- Shallow clone (
GIT_DEPTHtoo small) so the analyzer has no commit range to diff and finds no history to scan. SECRET_DETECTION_HISTORIC_SCANexpectations vs default behaviour — on default pipelines only the new commits are scanned, which can be empty for some ref types.- Detached/MR pipelines where the computed commit range collapses to nothing.
SECRET_DETECTION_EXCLUDED_PATHSor a narrow scan path excluding everything.- Overridden template variables (wrong
SECRET_DETECTION_IMAGE_SUFFIX, disabled rules) leaving no files in scope.
How to Reproduce the Error
Include the template with an aggressive shallow clone:
include:
- template: Security/Secret-Detection.gitlab-ci.yml
variables:
GIT_DEPTH: 1
On a pipeline where the single fetched commit yields no scannable diff, the job logs:
[INFO] No matching files. Skipping detect-secrets...
0 findings.
Job succeeded
Diagnostic Commands
Read-only checks to confirm the analyzer truly had nothing to scan:
# How deep is the clone the analyzer sees? (run inside the job)
git rev-list --count HEAD
git log --oneline -5
# Are there commits across all refs to scan?
git log --all --oneline | wc -l
# Print the secret-detection variables in effect
env | grep -i secret_detection
# Confirm the working tree actually has files in scope
git ls-files | head
1
0
SECRET_DETECTION_EXCLUDED_PATHS=
A git rev-list --count HEAD of 1 and an empty git log --all together explain “no commits to scan”: the shallow clone left the analyzer nothing to diff.
Step-by-Step Resolution
1. Give the analyzer enough history
Secret detection diffs commits, so a depth of 1 starves it. Fetch full history for the scan:
variables:
GIT_DEPTH: 0 # full clone so history scanning has commits to diff
include:
- template: Security/Secret-Detection.gitlab-ci.yml
GIT_DEPTH: 0 is the most common fix — it ensures the analyzer can build a real commit range.
2. Scan the full history when you need it
To scan the entire repository history (e.g. a first onboarding scan), enable the historic scan:
variables:
SECRET_DETECTION_HISTORIC_SCAN: "true"
This walks every commit reachable from the refs, not just the new ones, so it never collapses to an empty set on quiet branches.
3. Check exclusions and paths
Confirm you have not excluded everything. Review the excluded paths variable:
variables:
SECRET_DETECTION_EXCLUDED_PATHS: "spec, test" # not "*" or the repo root
An over-broad exclusion (or an accidental ./*) removes all files from scope and produces the same “no matching files” log.
4. Don’t override yourself out of a scan
If you customised the job, make sure your overrides still leave files in scope and the rules enabled:
secret_detection:
variables:
SECRET_DETECTION_EXCLUDED_PATHS: ""
rules:
- if: $CI_COMMIT_BRANCH
Removing default rules can prevent the job from running on the ref where you expect coverage; keep a rule that matches your branches and MRs.
5. Re-run and verify it actually scanned
A working scan logs the files or commits examined and a non-zero scan time. If you still see “No matching files,” widen GIT_DEPTH further and remove path exclusions one at a time.
Prevention and Best Practices
- Set
GIT_DEPTH: 0for any history-diffing security scanner (secret detection, license scanning) so it never starves on a shallow clone. - Run a one-time
SECRET_DETECTION_HISTORIC_SCAN: "true"when onboarding a repo, then rely on incremental scans afterwards. - Treat a green-but-skipped scan as a failure in review: assert that the job reports scanned files, not just exit 0.
- Keep
SECRET_DETECTION_EXCLUDED_PATHSminimal and explicit so you never silently exclude the whole tree. - A failing or empty scan log dropped into the free incident assistant will flag whether depth or exclusions caused the skip. More patterns live in the GitLab CI/CD guides.
Related Errors
[ERRO] fatal: detected dubious ownership in repository— a Gitleaks/git ownership error that also stops the scanner; mark the dir safe withgit config --global --add safe.directory.No analyzer matched— the template selected an analyzer image that doesn’t apply; checkSECRET_DETECTION_IMAGE_SUFFIX.fatal: reference is not a tree— a shallow clone is missing a referenced commit, the same depth problem from a different subsystem.
Frequently Asked Questions
The job is green — isn’t that good?
No. “No matching files. Skipping…” means it scanned nothing and still exited 0. A passing secret-detection job that scanned zero files gives false assurance. Always verify the log reports files or commits examined.
Why does a shallow clone break secret detection specifically?
The analyzer diffs commits to find newly introduced secrets. With GIT_DEPTH: 1 there is no commit range to diff, so it has nothing to scan. Set GIT_DEPTH: 0 to give it the history it needs.
Should I always enable historic scans?
Run a historic scan once when adding a repo to catch secrets already in history, then rely on incremental scans for speed. Always-on historic scanning is slower and rarely necessary after the initial pass.
Could exclusions be hiding everything?
Yes. An over-broad SECRET_DETECTION_EXCLUDED_PATHS (or a stray ./*) removes all files from scope, producing the same skip message. Print the variable with env | grep -i secret_detection and trim it until files are in scope.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.