hashicorp/nomad · error

could not parse value as bytes: %v

Error message

could not parse value as bytes: %v

What it means

parseQuotaMegabytes converts a quota value into megabytes. For string values it delegates to hashicorp/go-humanize's ParseBytes; if the string is not a recognizable byte quantity (number + optional unit), it returns "could not parse value as bytes" wrapping the underlying error. Quota files must express sizes either as human-readable byte strings or plain integer megabytes.

Source

Thrown at command/quota_apply.go:365

		return nil, fmt.Errorf("invalid variables limit: %v", err)
	}
	hostVolumesLimit, err := parseQuotaMegabytes(m["host_volumes"])
	if err != nil {
		return nil, fmt.Errorf("invalid host_volumes limit: %v", err)
	}

	return &api.QuotaStorageResources{
		VariablesMB:   variablesLimit,
		HostVolumesMB: hostVolumesLimit,
	}, nil
}

func parseQuotaMegabytes(raw any) (int, error) {
	switch val := raw.(type) {
	case string:
		b, err := humanize.ParseBytes(val)
		if err != nil {
			return 0, fmt.Errorf("could not parse value as bytes: %v", err)
		}
		return int(b >> 20), nil
	case int:
		return val, nil
	case nil:
		return 0, nil
	default:
		return 0, fmt.Errorf("invalid type %T", raw)
	}
}

func parseDeviceResource(result *[]*api.RequestedDevice, list *ast.ObjectList) error {
	for idx, o := range list.Items {
		if l := len(o.Keys); l == 0 {
			return multierror.Prefix(fmt.Errorf("missing device name"), fmt.Sprintf("resources, device[%d]->", idx))
		} else if l > 1 {
			return multierror.Prefix(fmt.Errorf("only one name may be specified"), fmt.Sprintf("resources, device[%d]->", idx))
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rewrite the value using units go-humanize understands: "500MB", "1GiB", "2GB", or "1024KB".
  2. Remove commas and stray whitespace: use "1024MB" not "1,024 MB".
  3. Inspect the wrapped error message for the exact position/character that failed parsing.
  4. Switch to an unquoted integer if you want to specify the limit directly in megabytes.

Example fix

// before
memory = "1,024 MB"
// after
memory = "1024MB"
Defensive patterns

Strategy: validation

Validate before calling

if s, ok := raw.(string); ok {
    if _, err := humanize.ParseBytes(s); err != nil {
        return fmt.Errorf("quota size %q is not parseable as bytes: %w", s, err)
    }
}

Type guard

func parseableBytes(v any) bool {
    s, ok := v.(string)
    if !ok {
        return true // ints and nil are accepted directly
    }
    _, err := humanize.ParseBytes(s)
    return err == nil
}

Prevention

When it happens

Trigger: A quota spec's size field (memory, variables, host_volumes) is a string like "5 giga", "100", "MB", "1,000MB", or contains a trailing space/currency symbol that ParseBytes rejects. Note bare numeric strings like "100" actually parse as bytes, often surprising users who meant megabytes.

Common situations: Typos in units, comma thousands separators ("1,024MB"), locale-decimal values ("1,5GB"), or quoting an integer when the file format expects an int and vice versa.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/801e8ee125206241. Report an issue: GitHub.