{"record":{"id":"a6cbb2f1842298b2","repo":"crowdsecurity/crowdsec","slug":"hostname-is-not-valid","errorCode":null,"errorMessage":"hostname is not valid","messagePattern":"hostname is not valid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/acquisition/modules/syslog/internal/parser/rfc3164/parse.go","lineNumber":124,"sourceCode":"\t}\n\tr.position++\n\treturn nil\n}\n\nfunc (r *RFC3164) parseHostname() error {\n\thostname := []byte{}\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\thostname = append(hostname, c)\n\t\tr.position++\n\t}\n\tif r.strictHostname {\n\t\tif !utils.IsValidHostnameOrIP(string(hostname)) {\n\t\t\treturn errors.New(\"hostname is not valid\")\n\t\t}\n\t}\n\tif len(hostname) == 0 {\n\t\treturn errors.New(\"hostname is empty\")\n\t}\n\tr.Hostname = string(hostname)\n\treturn nil\n}\n\n//We do not enforce tag len as quite a lot of syslog client send tags with more than 32 chars\nfunc (r *RFC3164) parseTag() error {\n\ttag := []byte{}\n\ttmpPid := []byte{}\n\tpidEnd := false\n\thasPid := false\n\tfor r.position < r.len {\n\t\tc := r.buf[r.position]\n\t\tif !utils.IsAlphaNumeric(c) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/syslog/internal/parser/rfc3164/parse.go#L106-L142","documentation":"parseHostname reads bytes up to the next space as the hostname, and when the parser is created with the WithStrictHostname() option it validates that value with utils.IsValidHostnameOrIP. If the field contains characters that make it neither a valid hostname nor an IP, it returns 'hostname is not valid'. It exists because strict mode guarantees only well-formed hostnames/IPs end up in RFC3164.Hostname.","triggerScenarios":"Calling Parse (after NewRFC3164Parser(WithStrictHostname())) on a message whose token after the timestamp is not a valid hostname or IP: spaces are absent so the whole remaining text is grabbed, or the token contains characters like '_', '/', '#', trailing punctuation, or a bare label like '-' .","commonSituations":"Messages missing the hostname field entirely so the tag text ('sshd[123]:...') is parsed as the hostname and rejected; devices emitting hostnames with underscores (invalid per RFC but common); relay servers that substitute a placeholder like '-' or '[unknown]'; enabling WithStrictHostname after previously accepting lax input.","solutions":["Inspect the offending message's token after the timestamp and check it with utils.IsValidHostnameOrIP to see exactly why it fails.","Drop the WithStrictHostname() option if your sources emit non-RFC-compliant hostnames (underscores, placeholders) and you do not need strict validation.","Fix the sending device or add a relay/rewrite so it emits a valid hostname or IP as the third field.","Ensure the hostname field is present in the message; a missing hostname makes the tag text be read as hostname and fail validation.","Update the acquisition source configuration so messages from that device are not routed through this strict parser."],"exampleFix":"// before\nparser := NewRFC3164Parser(WithStrictHostname())\nparser.Parse([]byte(\"<34>Feb  3 09:12:01 my_host sshd[123]: msg\")) // hostname is not valid\n\n// after: remove strict mode for non-RFC hostnames\nparser := NewRFC3164Parser()\nparser.Parse([]byte(\"<34>Feb  3 09:12:01 my_host sshd[123]: msg\"))","handlingStrategy":"validation","validationCode":"func hostnameTokenLooksValid(msg string) bool {\n\t// hostname is the token right after PRI + timestamp (32 chars for 'Jan 02 15:04:05')\n\tconst tsLen = len(\"Jan 02 15:04:05\")\n\tstart := 1 + len(\"<34>\") + tsLen + 1\n\tif len(msg) <= start { return false }\n\trest := msg[start:]\n\ttok := rest\n\tif i := strings.IndexByte(rest, ' '); i >= 0 { tok = rest[:i] }\n\treturn utils.IsValidHostnameOrIP(tok)\n}","typeGuard":"func isPlausibleHostname(s string) bool {\n\tif s == \"\" || len(s) > 255 { return false }\n\tfor _, c := range s {\n\t\tif !(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '-' || c == '.') {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"if err := parser.Parse(line); err != nil {\n\tif strings.Contains(err.Error(), \"hostname is not valid\") {\n\t\tlog.Warnf(\"non-RFC hostname in %q, dropping strict mode or rejecting\", line)\n\t}\n}","preventionTips":["Only enable WithStrictHostname() when all sources emit RFC-compliant hostnames or IPs","Reject underscores/placeholders ('-', '[unknown]') at the relay before acquisition","Always include a hostname field in message templates on senders","Pre-check tokens with utils.IsValidHostnameOrIP in tests covering your real log samples"],"tags":["syslog","rfc3164","hostname","validation"],"backgroundTag":"invalid-identifier-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"}