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

  1. Ensure the lat1 value passed to Distance is a plain decimal number string (e.g. "48.8566").
  2. Guard in the expression with a numeric check before calling Distance, or normalize the field upstream in the parser.
  3. Strip units/direction suffixes and replace commas with dots before the value reaches the helper.
  4. 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

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


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