crowdsecurity/crowdsec · error

hostname is empty

Error message

hostname is empty

What it means

parseHostname collects the bytes between the timestamp and the next space; if the very next byte is a space (or the message ends there), the collected hostname is empty and the parser returns 'hostname is empty'. It is thrown because RFC3164 requires a hostname field and r.Hostname cannot meaningfully be set to an empty string.

Source

Thrown at pkg/acquisition/modules/syslog/internal/parser/rfc3164/parse.go:128

func (r *RFC3164) parseHostname() error {
	hostname := []byte{}
	for r.position < r.len {
		c := r.buf[r.position]
		if c == ' ' {
			r.position++
			break
		}
		hostname = append(hostname, c)
		r.position++
	}
	if r.strictHostname {
		if !utils.IsValidHostnameOrIP(string(hostname)) {
			return errors.New("hostname is not valid")
		}
	}
	if len(hostname) == 0 {
		return errors.New("hostname is empty")
	}
	r.Hostname = string(hostname)
	return nil
}

//We do not enforce tag len as quite a lot of syslog client send tags with more than 32 chars
func (r *RFC3164) parseTag() error {
	tag := []byte{}
	tmpPid := []byte{}
	pidEnd := false
	hasPid := false
	for r.position < r.len {
		c := r.buf[r.position]
		if !utils.IsAlphaNumeric(c) {
			break
		}
		tag = append(tag, c)
		r.position++

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the raw message bytes: there must be exactly one space between the timestamp and the hostname, and the hostname must be present.
  2. Fix the emitting device or relay configuration so it includes a hostname field (e.g. set a hostname template in rsyslog/syslog-ng).
  3. If your sources legitimately omit hostname, patch the pipeline upstream to insert a placeholder hostname before parsing.
  4. If the line is being truncated in transit, increase the syslog line/max message size limit on the collector.

Example fix

// before: double space, empty hostname field
r.Parse([]byte("<34>Feb  3 09:12:01  sshd[123]: msg")) // hostname is empty

// after
r.Parse([]byte("<34>Feb  3 09:12:01 myhost sshd[123]: msg"))
Defensive patterns

Strategy: validation

Validate before calling

func hasHostnameField(msg string) bool {
	// after PRI and 15-char syslog timestamp there must be a non-space hostname token
	const tsLen = len("Jan 02 15:04:05")
	i := strings.IndexByte(msg, '>')
	if i < 0 { return false }
	rest := msg[i+1+tsLen:]
	return len(rest) > 0 && rest[0] != ' '
}

Try / catch

if err := parser.Parse(line); err != nil {
	if strings.Contains(err.Error(), "hostname is empty") {
		line = normalizeMissingHostname(line) // rewrite upstream or log and drop
	}
}

Prevention

When it happens

Trigger: Calling Parse on a message with two consecutive spaces after the timestamp ('<34>Feb 3 09:12:01 tag: msg'), or a message that ends immediately after the timestamp with nothing following.

Common situations: Log forwarders that strip or blank the hostname field; manually crafted test lines with an extra space; devices configured without a hostname emitting an empty field; truncation of long syslog lines that cuts the hostname off.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/5895d4cba92549ff. Report an issue: GitHub.