{"record":{"id":"6da000853a796515","repo":"crowdsecurity/crowdsec","slug":"pri-must-be-a-number-6da000","errorCode":null,"errorMessage":"PRI must be a number","messagePattern":"PRI must be a number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/acquisition/modules/syslog/internal/parser/rfc5424/parse.go","lineNumber":59,"sourceCode":"}\n\nfunc (r *RFC5424) parsePRI() error {\n\tpri := 0\n\n\tif r.buf[r.position] != '<' {\n\t\treturn errors.New(\"PRI must start with '<'\")\n\t}\n\n\tr.position++\n\n\tfor r.position < r.len {\n\t\tc := r.buf[r.position]\n\t\tif c == '>' {\n\t\t\tr.position++\n\t\t\tbreak\n\t\t}\n\t\tif c < '0' || c > '9' {\n\t\t\treturn errors.New(\"PRI must be a number\")\n\t\t}\n\t\tpri = pri*10 + int(c-'0')\n\t\tr.position++\n\t}\n\n\tif pri > 999 {\n\t\treturn errors.New(\"PRI must be up to 3 characters long\")\n\t}\n\n\tif r.position == r.len && r.buf[r.position-1] != '>' {\n\t\treturn errors.New(\"PRI must end with '>'\")\n\t}\n\n\tr.PRI = pri\n\treturn nil\n}\n\nfunc (r *RFC5424) parseVersion() error {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/syslog/internal/parser/rfc5424/parse.go#L41-L77","documentation":"parsePRI reads the syslog PRI field between '<' and '>'. Each character inside the brackets must be a decimal digit; if any character before the closing '>' is not '0'-'9', the parser rejects the line because PRI is defined by RFC 5424 as a numeric priority value. This indicates the line is not a well-formed RFC 5424 syslog message.","triggerScenarios":"Calling RFC5424.Parse on a line like \"<12ab>1 ...\" or \"<PR>1 ...\" where a non-digit character appears between '<' and '>'. Also fired when PRI exceeds 3 digits and the 4th character is not '>' (e.g. \"<12345...\" hits '4', a digit, then later overflow check applies; but \"<12x4>\" hits 'x' immediately).","commonSituations":"A syslog sender emitting RFC 3164 (legacy) lines, non-syslog garbage on the socket, a relay mangling the header, or UDP datagram fragmentation/interleaving corrupting the message start.","solutions":["Verify the sender actually emits RFC 5424 format: the message must begin \"<PRI>VERSION ...\"; use a different parser/decoder for RFC 3164 lines.","Inspect the raw line (log the buffer before Parse) to find what non-numeric character follows the '<'.","Check network path (UDP vs TCP framing) for truncation or interleaved data corrupting the message start."],"exampleFix":"// before\nparser.Parse([]byte(\"<34 Notice>1 2024-01-01T00:00:00Z host app 1 - msg\"))\n// after (PRI must be purely numeric)\nparser.Parse([]byte(\"<34>1 2024-01-01T00:00:00Z host app 1 - msg\"))","handlingStrategy":"validation","validationCode":"// Go: check the PRI is '<' followed by digits and '>' before parsing\nfunc looksLikePRI(line []byte) bool {\n\tif len(line) < 3 || line[0] != '<' {\n\t\treturn false\n\t}\n\ti := 1\n\tfor i < len(line) && line[i] != '>' {\n\t\tif line[i] < '0' || line[i] > '9' {\n\t\t\treturn false\n\t\t}\n\t\ti++\n\t}\n\treturn i < len(line) && line[i] == '>' && i <= 4\n}","typeGuard":null,"tryCatchPattern":"if err := parser.Parse(line); err != nil {\n\tif strings.Contains(err.Error(), \"PRI must be a number\") {\n\t\t// route to legacy/rfc3164 parser or drop to deadletter\n\t}\n}","preventionTips":["Pre-validate the line starts with '<digits>' before calling Parse","Confirm senders use RFC 5424 format, not RFC 3164","Log raw malformed lines for diagnosis instead of silently dropping them"],"tags":["syslog","rfc5424","parsing","malformed-input"],"backgroundTag":"invalid-argument-format","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}