{"record":{"id":"73defc14ff160965","repo":"projectdiscovery/nuclei","slug":"include-directive-preprocessing-is-disabled","errorCode":null,"errorMessage":"include directive preprocessing is disabled","messagePattern":"include directive preprocessing is disabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/utils/yaml/preprocess.go","lineNumber":53,"sourceCode":"var TemplateBaseDirProvider func() string\n\n// PreProcess all include directives. templatePath is the path of the template\n// currently being processed and is used to resolve relative include paths and\n// to validate them.\nfunc PreProcess(data []byte, templatePath string) ([]byte, error) {\n\treturn preProcess(data, templatePath, make(map[string]struct{}), 0)\n}\n\nfunc preProcess(data []byte, templatePath string, includeStack map[string]struct{}, depth int) ([]byte, error) {\n\t// find all matches like !include:path\\n\n\t// FindAllSubmatchIndex is used (instead of FindAllSubmatch) so each match\n\t// carries its own offset; relying on bytes.Index would always resolve to the\n\t// first occurrence and incorrectly pad repeated include directives.\n\timportMatches := reImportsPattern.FindAllSubmatchIndex(data, -1)\n\thasImportDirectives := len(importMatches) > 0\n\n\tif hasImportDirectives && StrictSyntax {\n\t\treturn data, errors.New(\"include directive preprocessing is disabled\")\n\t}\n\n\tif !hasImportDirectives {\n\t\treturn data, nil\n\t}\n\n\t// Expand each directive in place using its own offset. A strings.Replacer\n\t// cannot be used here because it collapses identical directive lines onto a\n\t// single replacement, which would reuse the first occurrence's indentation\n\t// for every later occurrence.\n\tvar out bytes.Buffer\n\tlastEnd := 0\n\n\tfor _, match := range importMatches {\n\t\tmatchStart, matchEnd := match[0], match[1]\n\n\t\tvar includeFileName string\n\t\tif len(match) > 3 && match[2] >= 0 {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/utils/yaml/preprocess.go#L35-L71","documentation":"The YAML preprocessor (pkg/utils/yaml/preprocess.go:52) expands `!include:path` directives only when pkg/utils/yaml.StrictSyntax is false. The nuclei binary sets yaml.StrictSyntax = !options.NoStrictSyntax (internal/runner/runner.go:189), so strict mode is ON by default and any template containing an include directive is rejected before expansion — even when the include path is valid. The -nss/-no-strict-syntax flag (cmd/nuclei/main.go:298) is the intended opt-out.","triggerScenarios":"Loading a template containing `!include:file` lines with default CLI settings (strict on); CI pipelines running nuclei without -nss; re-enabling strict after previously running lax.","commonSituations":"Community or internal templates that rely on include preprocessing; version upgrades where templates began shipping includes; SDK users who set yaml.StrictSyntax=true explicitly.","solutions":["Run nuclei with `-nss` / `-no-strict-syntax` so include directives preprocess","Inline the included file's content into the template to stay strict-compliant","SDK users: leave yaml.StrictSyntax false (or set parser.NoStrictSyntax) for templates using includes","Audit templates for includes: `grep -rn '!include:' templates/`"],"exampleFix":"# before\nnuclei -t tmpl-with-include.yaml\n\n# after\nnuclei -nss -t tmpl-with-include.yaml","handlingStrategy":"validation","validationCode":"import \"regexp\"\n\nvar includeRe = regexp.MustCompile(`(?m)^\\s*!include:`)\n\nif includeRe.Match(data) {\n    // either opt out of strict mode or reject the template explicitly\n    yaml.StrictSyntax = false // equivalent of -nss\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize whether your team uses !include; if yes, always run nuclei with -nss","grep new templates for '!include:' before adding them to strict-mode pipelines","In SDK code, set yaml.StrictSyntax=false once at init if includes are expected"],"tags":["go","nuclei","yaml","templates","configuration","cli"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}