crowdsecurity/crowdsec · error
long1 is not a float : %v
Error message
long1 is not a float : %v
What it means
The Distance expr helper parses all four coordinate arguments as float64 strings. This error is thrown when the long1 (first longitude) argument cannot be parsed by strconv.ParseFloat; the helper logs a warning and returns (0.0, error).
Source
Thrown at pkg/exprhelpers/helpers.go:402
// 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 {
log.Warningf("long2 is not a float : %v", err)
return 0.0, fmt.Errorf("long2 is not a float : %v", err)
}
// either set of coordinates is 0,0, return 0 to avoid FPs
if (lat1f == 0.0 && long1f == 0.0) || (lat2f == 0.0 && long2f == 0.0) {View on GitHub (pinned to 909b515798)
Solutions
- Pass long1 as a plain decimal string such as "2.3522".
- Normalize/cleanse the longitude field in the parser (strip symbols, convert commas) before Distance is evaluated.
- Add a numeric precondition in the expression so Distance is only called with valid coordinates.
- Check that the GeoIP enrichment actually ran and populated the field; empty strings always fail ParseFloat.
Example fix
// before Distance(lat, "2.3522°", lat2, long2) // after Distance(lat, "2.3522", lat2, long2)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := strconv.ParseFloat(long1, 64); err != nil {
// skip Distance call
} Type guard
func isFloat(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
} Try / catch
expr: use isNumeric(long1) in the condition guarding the Distance call; treat its error return as 'unknown distance', not 0
Prevention
- Strip degree symbols and direction letters from longitude fields during parsing
- Verify GeoIP enrichment output for the source IP before geo distance checks
- Cover geo parsing with unit tests using real log samples
When it happens
Trigger: Calling exprhelpers.Distance where long1 is non-numeric — empty string, "2.3522E" (truncated exponent), "2,3522", or a field holding a placeholder like "unknown".
Common situations: GeoIP enrichment that produced empty or sentinel longitude values; CSV-sourced numbers with comma decimals; fields concatenated with units ("2.3522°").
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
- lat1 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/690869443b472f03.
Report an issue: GitHub.