crowdsecurity/crowdsec · error

EOL after timestamp

Error message

EOL after timestamp

What it means

After collecting a non-empty timestamp, parseTimestamp checks that the buffer has not ended. RFC 5424 requires hostname, appname, procid, msgid and structured data after the timestamp, so a line ending right after the timestamp is truncated and rejected.

Solutions

  1. Fix framing so complete syslog frames are delivered (octet counting per RFC 6587 for TCP).
  2. Verify the sending device includes hostname/appname/procid/msgid/structured-data after the timestamp.
  3. Check any intermediate transformation (forwarder, log shipper) isn't truncating the message.

Example fix

// before (nothing after timestamp)
parser.Parse([]byte("<34>1 2024-01-01T00:00:00Z"))
// after (full header + message)
parser.Parse([]byte("<34>1 2024-01-01T00:00:00Z host app 1 - msg"))
Defensive patterns

Strategy: validation

Validate before calling

// Go: require content after the timestamp token
func hasFieldsAfterTimestamp(line []byte) bool {
	// header must have at least '<P>1 TS host ...'
	parts := bytes.SplitN(line, []byte(" "), 5)
	return len(parts) == 5 && len(parts[3]) > 0
}

Try / catch

if err := parser.Parse(line); err != nil {
	if strings.Contains(err.Error(), "EOL after timestamp") {
		// flag the sender; frame is incomplete
	}
}

Prevention

When it happens

Trigger: Calling RFC5424.Parse on "<34>1 2024-01-01T00:00:00Z" — the timestamp loop stops at end of buffer with r.position == r.len, before any time parsing occurs.

Common situations: A device emitting timestamp-only messages, TCP framing dropping the rest of the frame, or a regex/filter upstream cutting the line.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at pkg/acquisition/modules/syslog/internal/parser/rfc5424/parse.go:111

		r.position += 2
		return nil
	}

	for r.position < r.len {
		c := r.buf[r.position]
		if c == ' ' {
			break
		}
		timestamp = append(timestamp, c)
		r.position++
	}

	if len(timestamp) == 0 {
		return errors.New("timestamp is empty")
	}

	if r.position == r.len {
		return errors.New("EOL after timestamp")
	}

	date, err := time.Parse(VALID_TIMESTAMP, string(timestamp))
	if err != nil {
		return errors.New("timestamp is not valid")
	}

	r.Timestamp = date

	r.position++

	if r.position >= r.len {
		return errors.New("EOL after timestamp")
	}

	return nil
}

View on GitHub (pinned to 909b515798)