hyperledger/fabric · error

value '%s' overflows uint32

Error message

value '%s' overflows uint32

What it means

byteSizeDecodeHook is a viper decode hook that converts size strings like "128mb" into a uint32 byte count. If the converted value exceeds math.MaxUint32 (about 4 GiB), the hook returns this error because the target config field is a uint32 and cannot hold the value.

Source

Thrown at common/viperutil/config_util.go:261

	re := regexp.MustCompile(`^(?P<size>[0-9]+)\s*(?i)(?P<unit>(k|m|g))b?$`)
	if re.MatchString(raw) {
		size, err := strconv.ParseUint(re.ReplaceAllString(raw, "${size}"), 0, 64)
		if err != nil {
			return data, nil
		}
		unit := re.ReplaceAllString(raw, "${unit}")
		switch strings.ToLower(unit) {
		case "g":
			size = size << 10
			fallthrough
		case "m":
			size = size << 10
			fallthrough
		case "k":
			size = size << 10
		}
		if size > math.MaxUint32 {
			return size, fmt.Errorf("value '%s' overflows uint32", raw)
		}
		return size, nil
	}
	return data, nil
}

func stringFromFileDecodeHook(f reflect.Kind, t reflect.Kind, data any) (any, error) {
	// "to" type should be string
	if t != reflect.String {
		return data, nil
	}
	// "from" type should be map
	if f != reflect.Map {
		return data, nil
	}
	v := reflect.ValueOf(data)
	switch v.Kind() {
	case reflect.String:

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Lower the configured size to at most ~4 GiB (e.g. "2gb" or a plain byte count <= 4294967295).
  2. Express the value in a smaller unit ("4096mb" instead of "4gb" still overflows — use "2048mb") only if the numeric result fits.
  3. Double-check the unit letter; a stray 'g' where 'm' was intended causes the overflow.
  4. If a larger limit is truly needed, change the target struct field type to uint64 and update the decode hook target kind.

Example fix

// before (config.yaml)
peer.gossip.state.checkInterval: 5gb  # if mapped to a uint32 size field
# after
size: 2048mb
Defensive patterns

Strategy: validation

Validate before calling

// Validate a byte-size config string fits uint32 before it reaches viper decode
var sizeRe = regexp.MustCompile(`^([0-9]+)\s*([kKmMgG])b?$`)
func fitsUint32(raw string) bool {
	m := sizeRe.FindStringSubmatch(raw)
	if m == nil { return true } // not unit-scaled, hook passes through
	n, _ := strconv.ParseUint(m[1], 10, 64)
	switch strings.ToLower(m[2]) {
	case "g": n <<= 20
	case "m": n <<= 10
	case "k": n <<= 0
	}
	return n <= math.MaxUint32
}

Type guard

func isSafeByteSize(v any) bool {
	s, ok := v.(string)
	if !ok { return true }
	return fitsUint32(s)
}

Try / catch

err := viper.Unmarshal(cfg, viperutil.DecodeHookFunc) // includes byteSizeDecodeHook
if err != nil {
	if strings.Contains(err.Error(), "overflows uint32") {
		return fmt.Errorf("config size too large (max ~4GiB): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Setting a viper config value (YAML file, flag, or env var via viperutil) that maps to a uint32 size field with a value like "5gb" or "4294967297b" — any size that, after unit scaling (k/m/g shifted <<10), exceeds 4294967295 bytes.

Common situations: Configuring large ledger/block sizes (e.g. absoluteMaxBytes: 2gb is fine, but 8gb overflows), copying cloud-provider sizes into Fabric config, or typos like "40gb" intended as "40mb".

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/05bd4f5700f09171. Report an issue: GitHub.