cloudflare/cloudflared · error

expected int, found %T for %v

Error message

expected int, found %T for %v 

What it means

Returned by configFileSettings.IntSlice while converting a []interface{} element to int: an element is not an int. The message has a formatting quirk (formats the value twice as %T then %v) and a trailing space; it identifies the list by name via the loop context.

Source

Thrown at config/configuration.go:347

					return nil, fmt.Errorf("expected string, found %T for %v", i, v)
				}
				strSlice[i] = str
			}
			return strSlice, nil
		}
		return nil, fmt.Errorf("expected string slice found %T for %s", raw, name)
	}
	return nil, nil
}

func (c *configFileSettings) IntSlice(name string) ([]int, error) {
	if raw, ok := c.Settings[name]; ok {
		if slice, ok := raw.([]interface{}); ok {
			intSlice := make([]int, len(slice))
			for i, v := range slice {
				str, ok := v.(int)
				if !ok {
					return nil, fmt.Errorf("expected int, found %T for %v ", v, v)
				}
				intSlice[i] = str
			}
			return intSlice, nil
		}
		if v, ok := raw.([]int); ok {
			return v, nil
		}
		return nil, fmt.Errorf("expected int slice found %T for %s", raw, name)
	}
	return nil, nil
}

func (c *configFileSettings) Generic(name string) (cli.Generic, error) {
	return nil, errors.New("option type Generic not supported")
}

func (c *configFileSettings) Bool(name string) (bool, error) {

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Remove quotes so every element parses as an integer (ports: [8080, 80]).
  2. If strings are expected, switch the consumer to StringSlice and convert with strconv.Atoi.
  3. Trim/handle the trailing-space message when matching on error text; prefer errors-wrapping over string comparison.

Example fix

// before (config.yml)
ports:
  - "8080"
  - 80
// after
ports:
  - 8080
  - 80
Defensive patterns

Strategy: type-guard

Validate before calling

// Go: validate all elements are ints before calling
allInts := func(raw []interface{}) bool {
    for _, v := range raw { if _, ok := v.(int); !ok { return false } }
    return true
}

Type guard

func asIntSlice(v interface{}) ([]int, bool) {
    list, ok := v.([]interface{}); if !ok { return nil, false }
    out := make([]int, len(list))
    for i, e := range list { n, ok := e.(int); if !ok { return nil, false }; out[i] = n }
    return out, true
}

Try / catch

is, err := settings.IntSlice("ports")
if err != nil {
    log.Printf("'ports' must be a list of unquoted ints: %v", err)
    return err
}

Prevention

When it happens

Trigger: Calling IntSlice(name) on a list containing non-integer elements, e.g. `ports: ["8080", 80]` where a quoted string sneaks into an integer list.

Common situations: Quoted numbers in YAML lists; mixed lists of ints and strings; auto-generated configs where numbers were serialized as strings.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/1c670422d6f7c4f8. Report an issue: GitHub.