projectdiscovery/nuclei · error

no templates provided for scan

Error message

no templates provided for scan

What it means

readSMBFile refuses inputs whose resolved SMB path is the share root (Path == ".") or that isDirectorySMBTarget flags as a directory. The file protocol only elaborates regular files, so directory inputs get a clean error instead of attempting a directory read over SMB.

Source

Thrown at internal/runner/runner.go:926

	return result, nil
}

func (r *Runner) executeTemplatesInput(store *loader.Store, engine *core.Engine) (*atomic.Bool, error) {
	if r.options.VerboseVerbose {
		for _, template := range store.Templates() {
			r.logAvailableTemplate(template.Path)
		}
		for _, template := range store.Workflows() {
			r.logAvailableTemplate(template.Path)
		}
	}

	finalTemplates := []*templates.Template{}
	finalTemplates = append(finalTemplates, store.Templates()...)
	finalTemplates = append(finalTemplates, store.Workflows()...)

	if len(finalTemplates) == 0 {
		return nil, errors.New("no templates provided for scan")
	}

	// pass input provider to engine
	// TODO: this should be not necessary after r.hmapInputProvider is removed + refactored
	if r.inputProvider == nil {
		return nil, errors.New("no input provider found")
	}
	results := engine.ExecuteScanWithOpts(context.Background(), finalTemplates, r.inputProvider, r.options.DisableClustering)
	return results, nil
}

// displayExecutionInfo prints parser stats, version info, and scan counts.
func (r *Runner) displayExecutionInfo(store *loader.Store) {
	// Display parser stats for templates loaded into the store.
	stats.Display(templates.TemplateSyntaxWarningStats)
	stats.Display(templates.TemplateSyntaxErrorStats)
	stats.Display(templates.TemplateRuntimeWarningStats)

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Point at a concrete file: \\server\share\docs\report.pdf
  2. Filter listing output so only regular files reach nuclei
  3. Enumerate first, then scan each file path individually

Example fix

# before
\\server\share
# after
\\server\share\docs\report.pdf
Defensive patterns

Strategy: validation

Validate before calling

import "strings"

// A file target needs at least host/share/file depth; host/share alone is a share root.
func namesSMBFile(s string) bool {
    t := strings.TrimSpace(s)
    lower := strings.ToLower(t)
    if !strings.HasPrefix(lower, "smb://") {
        lower = strings.TrimPrefix(lower, "smb://")
    }
    p := strings.Trim(strings.ReplaceAll(lower, "\\", "/"), "/")
    if p == t || p == "" {
        return false
    }
    return len(strings.Split(p, "/")) >= 3
}

Prevention

When it happens

Trigger: Passing \\server\share or \\server\share\folder (or smb://host/share/) as a file-protocol target; directory entries from an SMB listing fed back unfiltered.

Common situations: Target lists containing share roots; walking SMB enumerations without filtering; assuming nuclei recurses into SMB directories.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/c3bfe21b468a801b. Report an issue: GitHub.