crowdsecurity/crowdsec · error
lat1 is not a float : %v
Error message
lat1 is not a float : %v
What it means
The Distance expr helper computes geographic distance between two lat/long coordinate pairs given as strings. This error is thrown when the lat1 argument cannot be parsed as a float64 via strconv.ParseFloat; the helper logs a warning and returns (0.0, error).
Source
Thrown at pkg/exprhelpers/helpers.go:395
// func Lower(s string) string {
func Lower(params ...any) (any, error) {
s := params[0].(string)
return strings.ToLower(s), nil
}
// func Distance(lat1 string, long1 string, lat2 string, long2 string) (float64, error) {
func Distance(params ...any) (any, error) {
lat1 := params[0].(string)
long1 := params[1].(string)
lat2 := params[2].(string)
long2 := params[3].(string)
lat1f, err := strconv.ParseFloat(lat1, 64)
if err != nil {
log.Warningf("lat1 is not a float : %v", err)
return 0.0, fmt.Errorf("lat1 is not a float : %v", err)
}
long1f, err := strconv.ParseFloat(long1, 64)
if err != nil {
log.Warningf("long1 is not a float : %v", err)
return 0.0, fmt.Errorf("long1 is not a float : %v", err)
}
lat2f, err := strconv.ParseFloat(lat2, 64)
if err != nil {
log.Warningf("lat2 is not a float : %v", err)
return 0.0, fmt.Errorf("lat2 is not a float : %v", err)
}
long2f, err := strconv.ParseFloat(long2, 64)
if err != nil {View on GitHub (pinned to 909b515798)
Solutions
- Ensure the lat1 value passed to Distance is a plain decimal number string (e.g. "48.8566").
- Guard in the expression with a numeric check before calling Distance, or normalize the field upstream in the parser.
- Strip units/direction suffixes and replace commas with dots before the value reaches the helper.
- Handle the returned error/0.0 result in the expression so bad coordinates don't silently yield 0 distance.
Example fix
// before (expression) distance(evt.Enriched.geo.latitude, evt.Enriched.geo.longitude, refLat, refLong) > 100 // after (normalize first in parser) normalized: evt.Enriched.geo.latitude replace "," with "." | trim suffixes; guard isNumeric(lat) && isNumeric(long)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := strconv.ParseFloat(lat1, 64); err != nil {
// skip Distance call
} Type guard
func isFloat(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
} Try / catch
expr: guard with isNumeric(lat1) && isNumeric(long1) && isNumeric(lat2) && isNumeric(long2) before calling Distance, and handle its error return instead of using 0.0 blindly
Prevention
- Normalize geo fields in the parser: trim whitespace, strip units, convert comma decimals
- Only run Distance when GeoIP enrichment actually populated the fields
- Log-and-validate enriched geo fields in a test parser pipeline
When it happens
Trigger: Calling exprhelpers.Distance(lat1, long1, lat2, long2) where lat1 is a non-numeric string such as "", "N/A", "48.8566 N", or an event field that was expected to hold a number but holds text.
Common situations: Log fields carrying geolocation data with units/hemisphere suffixes; empty fields when geolocation enrichment failed; locale-formatted numbers using comma decimal separators ("48,85").
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
- long1 is not a float : %v
- lat2 is not a float : %v
- long2 is not a float : %v
- unable to parse time
- unable to parse duration
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/499d890c6a979407.
Report an issue: GitHub.