crowdsecurity/crowdsec · error
unable to parse time
Error message
unable to parse time
What it means
ParseTimeFail is a sentinel error meaning an RFC3339 timestamp string could not be parsed by time.Parse. In crowdsec it surfaces when alert start_at/stop_at fields submitted to CreateAlert lack the RFC3339 format (e.g. missing timezone offset).
Source
Thrown at pkg/database/errors.go:14
package database
import "errors"
var (
UserExists = errors.New("user already exist")
UserNotExists = errors.New("user doesn't exist")
HashError = errors.New("unable to hash")
InsertFail = errors.New("unable to insert row")
QueryFail = errors.New("unable to query")
UpdateFail = errors.New("unable to update")
DeleteFail = errors.New("unable to delete")
ItemNotFound = errors.New("object not found")
ParseTimeFail = errors.New("unable to parse time")
ParseDurationFail = errors.New("unable to parse duration")
MarshalFail = errors.New("unable to serialize")
BulkError = errors.New("unable to insert bulk")
ParseType = errors.New("unable to parse type")
InvalidIPOrRange = errors.New("invalid ip address / range")
InvalidFilter = errors.New("invalid filter")
)
View on GitHub (pinned to 909b515798)
Solutions
- Format timestamps with time.RFC3339 (time.Now().Format(time.RFC3339)) before submitting.
- Ensure the string uses 'T' separator and an explicit offset/Z: convert with time.Parse then re-format.
- If ingesting third-party JSON, normalize the date field before calling the client API.
- Log the offending value (already included in the wrapped error) and correct the producer.
Example fix
// before
alert.StartAt = ptr("2024-05-01 12:00:00")
// after
alert.StartAt = ptr(time.Now().UTC().Format(time.RFC3339)) Defensive patterns
Strategy: validation
Validate before calling
func validRFC3339(s string) bool {
_, err := time.Parse(time.RFC3339, s)
return err == nil
}
// call before submitting: validRFC3339(alert.StartAt) Try / catch
if _, _, _, err := client.CreateAlert(ctx, alert); err != nil {
if errors.Is(err, database.ParseTimeFail) {
return fmt.Errorf("fix start_at/stop_at to RFC3339: %w", err)
}
return err
} Prevention
- Always generate timestamps with time.Now().Format(time.RFC3339)
- Validate date fields at API boundaries before calling the database layer
- Reject naive (offset-less) datetime strings at producer level
When it happens
Trigger: CreateAlert (via UpdateCommunityBlocklist or alert ingestion) when alertItem.StartAt or alertItem.StopAt is not a valid RFC3339 string, e.g. "2024-01-01 10:00:00" instead of "2024-01-01T10:00:00Z".
Common situations: Custom automation or bouncers posting alerts with locally formatted dates, hand-written JSON payloads without the 'T' separator or timezone, clients in non-UTC environments dropping the offset.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse duration
- unable to parse type
- no database configuration provided
- unable to update
- unable to delete
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/7c3ab65ff1c2d33a.
Report an issue: GitHub.