slackhq/nebula · error

entry %v.mtu in tun.routes is not an integer: %v

Error message

entry %v.mtu in tun.routes is not an integer: %v

What it means

The mtu value of a tun.routes entry is neither an int nor a string parseable as an integer. parseRoutes accepts a native int or a numeric string (via strconv.Atoi); any other type, or a non-numeric string, produces this wrapped conversion error.

Source

Thrown at overlay/route.go:103

	}

	routes := make([]Route, len(rawRoutes))
	for i, r := range rawRoutes {
		m, ok := r.(map[string]any)
		if !ok {
			return nil, fmt.Errorf("entry %v in tun.routes is invalid", i+1)
		}

		rMtu, ok := m["mtu"]
		if !ok {
			return nil, fmt.Errorf("entry %v.mtu in tun.routes is not present", i+1)
		}

		mtu, ok := rMtu.(int)
		if !ok {
			mtu, err = strconv.Atoi(rMtu.(string))
			if err != nil {
				return nil, fmt.Errorf("entry %v.mtu in tun.routes is not an integer: %v", i+1, err)
			}
		}

		if mtu < 500 {
			return nil, fmt.Errorf("entry %v.mtu in tun.routes is below 500: %v", i+1, mtu)
		}

		rRoute, ok := m["route"]
		if !ok {
			return nil, fmt.Errorf("entry %v.route in tun.routes is not present", i+1)
		}

		r := Route{
			Install: true,
			MTU:     mtu,
		}

		r.Cidr, err = netip.ParsePrefix(fmt.Sprintf("%v", rRoute))

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Set mtu to a plain integer (e.g. mtu: 1300)
  2. If quoted, ensure the string is purely numeric: mtu: "1300"
  3. Remove unit suffixes or decimals from the value
  4. Check the inner %v for the underlying strconv error to see the offending value

Example fix

// before
- mtu: "auto"
  route: 10.0.0.0/24
// after
- mtu: 1300
  route: 10.0.0.0/24
Defensive patterns

Strategy: validation

Validate before calling

switch v := m["mtu"].(type) {
case int:
    // ok
case string:
    if _, err := strconv.Atoi(v); err != nil {
        return fmt.Errorf("mtu %q is not an integer", v)
    }
default:
    return fmt.Errorf("mtu must be int or numeric string")
}

Type guard

func isIntOrNumericString(v any) bool {
    switch t := v.(type) {
    case int:
        return true
    case string:
        _, err := strconv.Atoi(t)
        return err == nil
    }
    return false
}

Prevention

When it happens

Trigger: getAllRoutesFromConfig sees mtu as a bool, float-in-YAML (e.g. 1300.0), quoted garbage like mtu: "auto", or an empty string.

Common situations: Writing mtu: "auto" or "default" expecting the library to pick a value; YAML unquoted floats or unit suffixes like 1300 bytes; templating that renders numbers with decimals.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/1966e8d7c8cc8115. Report an issue: GitHub.