nats-io/nats-server · error
must be int64 or string
Error message
must be int64 or string
What it means
getStorageSize() in nats-server (server/opts.go:2495) parses a JetStream storage size that config may express as either an int64 (bytes) or a string with a size suffix. If the value is neither an int64 nor a string, the function returns 'must be int64 or string'. This protects against wrong-typed config values (e.g. YAML/JSON numbers decoded as float64 or bool).
Source
Thrown at server/opts.go:2503
}
}
acc.jsLimits = map[string]JetStreamAccountLimits{_EMPTY_: jsLimits}
default:
return &configErr{tk, fmt.Sprintf("Expected map, bool or string to define JetStream, got %T", v)}
}
return nil
}
// takes in a storage size as either an int or a string and returns an int64 value based on the input.
func getStorageSize(v any) (int64, error) {
_, ok := v.(int64)
if ok {
return v.(int64), nil
}
s, ok := v.(string)
if !ok {
return 0, fmt.Errorf("must be int64 or string")
}
if s == _EMPTY_ {
return 0, nil
}
suffix := s[len(s)-1:]
prefix := s[:len(s)-1]
num, err := strconv.ParseInt(prefix, 10, 64)
if err != nil {
return 0, err
}
suffixMap := map[string]int64{"K": 10, "M": 20, "G": 30, "T": 40}
mult, ok := suffixMap[suffix]
if !ok {
return 0, fmt.Errorf("sizes defined as strings must end in K, M, G, T")View on GitHub (pinned to 3a66a489d2)
Solutions
- Convert the value to int64 (bytes) or a string like "1G" before passing it
- If the value comes from JSON/YAML generic decoding, convert float64 to int64 first (int64(v.(float64)))
- Check the config section producing the value and fix its type
- Upgrade/patch config parsing so numeric values are decoded as int64
Example fix
// before limits["max_memory"] = 1024 // decoded as int or float64, not int64 // after limits["max_memory"] = int64(1024) // or as a string limits["max_memory"] = "1K"
Defensive patterns
Strategy: type-guard
Validate before calling
func validStorageSize(v any) bool {
switch t := v.(type) {
case int64:
return t >= 0
case string:
if t == "" { return true }
s := t[:len(t)-1]
_, err := strconv.ParseInt(s, 10, 64)
return err == nil && strings.ContainsAny(t[len(t)-1:], "KMGT")
}
return false
} Type guard
func asStorageSize(v any) (int64, bool) {
switch t := v.(type) {
case int64:
return t, true
case int:
return int64(t), true
case float64:
return int64(t), true
}
return 0, false
} Try / catch
if size, err := getStorageSize(v); err != nil {
return fmt.Errorf("storage size invalid: %w", err)
} Prevention
- Always use int64 for byte counts in Go config builders
- Normalize JSON/YAML-decoded float64 values to int64 before validation
- Prefer string sizes with explicit units ("1G") to avoid type ambiguity
When it happens
Trigger: Passing a value of any type other than int64 or string to getStorageSize, e.g. a JSON number decoded as float64/float32, a bool, a map, or an int (not int64) in parsed config used for JetStream limits (parseJetStreamLimits path).
Common situations: Writing a size as a plain YAML/JSON number that decodes to float64 instead of int64; using an int literal in Go config-building code instead of int64; feeding config from a generic map[string]any without normalizing types.
Related errors
- ack wait must be a positive value
- JS API timeout must be a positive value
- mqtt requires JetStream to be enabled if running in standalo
- %v
- expected port or host:port, got %T
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/493626e457cb2e27.
Report an issue: GitHub.