{"record":{"id":"4938f811f43972e0","repo":"projectdiscovery/nuclei","slug":"could-not-hex-decode-binary-s","errorCode":null,"errorMessage":"could not hex decode binary: %s","messagePattern":"could not hex decode binary: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/operators/matchers/compile.go","lineNumber":62,"sourceCode":"\n\t// Compile the regexes (with shared cache)\n\tfor _, regex := range matcher.Regex {\n\t\tif cached, err := cache.Regex().GetIFPresent(regex); err == nil && cached != nil {\n\t\t\tmatcher.regexCompiled = append(matcher.regexCompiled, cached)\n\t\t\tcontinue\n\t\t}\n\t\tcompiled, err := regexp.Compile(regex)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not compile regex: %s\", regex)\n\t\t}\n\t\t_ = cache.Regex().Set(regex, compiled)\n\t\tmatcher.regexCompiled = append(matcher.regexCompiled, compiled)\n\t}\n\n\t// Compile and validate binary Values in matcher\n\tfor _, value := range matcher.Binary {\n\t\tif decoded, err := hex.DecodeString(value); err != nil {\n\t\t\treturn fmt.Errorf(\"could not hex decode binary: %s\", value)\n\t\t} else {\n\t\t\tmatcher.binaryDecoded = append(matcher.binaryDecoded, string(decoded))\n\t\t}\n\t}\n\n\t// Compile the dsl expressions (with shared cache)\n\tfor _, dslExpression := range matcher.DSL {\n\t\tif cached, err := cache.DSL().GetIFPresent(dslExpression); err == nil && cached != nil {\n\t\t\tmatcher.dslCompiled = append(matcher.dslCompiled, cached)\n\t\t\tcontinue\n\t\t}\n\t\tcompiledExpression, err := govaluate.NewEvaluableExpressionWithFunctions(dslExpression, dsl.HelperFunctions)\n\t\tif err != nil {\n\t\t\treturn &dsl.CompilationError{DslSignature: dslExpression, WrappedError: err}\n\t\t}\n\t\t_ = cache.DSL().Set(dslExpression, compiledExpression)\n\t\tmatcher.dslCompiled = append(matcher.dslCompiled, compiledExpression)\n\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/operators/matchers/compile.go#L44-L80","documentation":"Template compilation error from Matcher.CompileMatchers (pkg/operators/matchers/compile.go:62). For `type: binary` matchers, every `binary:` entry is hex-decoded with hex.DecodeString at compile time; invalid hex (odd length or non-hex characters) returns this error including the offending value. Unlike word matchers' optional 'hex' encoding, binary matchers are strict.","triggerScenarios":"A binary matcher value with an odd number of hex digits ('4d5'), a '0x' prefix ('0x4d5a'), embedded whitespace, or a raw string pasted where hex was expected.","commonSituations":"Converting packet signatures/PoC byte sequences to templates and dropping a nibble; pasting 'MZ' style hex with separators (e.g. '4d 5a') or 0x prefixes from Wireshark/ghidra output.","solutions":["Ensure each binary value is an even-length pure hex string: strip spaces/colons/0x, then verify length % 2 == 0","Verify with a quick shell check: `echo -n '4d5a...' | xxd -r -p | xxd` round-trips","If the intent is to match literal text, use a word matcher instead of binary","Validate the template with `nuclei -validate -t template.yaml`"],"exampleFix":"# before\nbinary:\n  - '0x4d5a'\n# after\nbinary:\n  - '4d5a'","handlingStrategy":"validation","validationCode":"for _, b := range m.Binary {\n\tif len(b)%2 != 0 { return fmt.Errorf(\"odd-length hex %q\", b) }\n\tfor _, c := range b {\n\t\tif !strings.ContainsRune(\"0123456789abcdefABCDEF\", c) {\n\t\t\t\treturn fmt.Errorf(\"non-hex char %q in %q\", c, b)\n\t\t\t}\n\t}\n}","typeGuard":"func isPureHex(s string) bool {\n\tif len(s)%2 != 0 { return false }\n\t_, err := hex.DecodeString(s)\n\treturn err == nil\n}","tryCatchPattern":"if err := m.CompileMatchers(); err != nil && strings.Contains(err.Error(), \"could not hex decode binary\") {\n\t// strip 0x/spaces from the reported value and re-validate\n}","preventionTips":["Strip separators and 0x prefixes when pasting hex from packet tools","Always emit even-length lowercase hex when generating templates","Round-trip check: xxd -r -p | xxd -p"],"tags":["matcher","binary","hex","template","compile-time"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}