oracle/graal · error · IllegalArgumentException

Not starting with digits: {size}

Error message

Not starting with digits: {size}

What it means

The SIZE_OPTION_TYPE converter (used by --java.MaxDirectMemorySize and similar size options) scans the leading characters of the value and requires at least one leading digit before an optional single unit character. If the very first character is not a digit, it throws 'Not starting with digits'.

Source

Thrown at espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java:561

    public static final OptionKey<Path> PreInitializationClasslist = new OptionKey<>(EMPTY, PATH_OPTION_TYPE);

    private static final OptionType<Long> SIZE_OPTION_TYPE = new OptionType<>("Size", new Function<String, Long>() {
        private static final int K = 1024;

        @Override
        public Long apply(String size) {
            int idx = 0;
            int len = size.length();
            for (int i = 0; i < len; i++) {
                if (Character.isDigit(size.charAt(i))) {
                    idx++;
                } else {
                    break;
                }
            }

            if (idx == 0) {
                throw new IllegalArgumentException("Not starting with digits: " + size);
            }
            if (len - idx > 1) {
                throw new IllegalArgumentException("Unit prefix can be at most one character: " + size);
            }

            long result = Long.parseLong(size.substring(0, idx));

            if (idx < len) {
                switch (size.charAt(idx)) {
                    case 'T': // fallthrough
                    case 't':
                        return result * K * K * K * K;
                    case 'G': // fallthrough
                    case 'g':
                        return result * K * K * K;
                    case 'M': // fallthrough
                    case 'm':
                        return result * K * K;

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Write the value as a plain number of bytes or number+unit with the digit first: 1073741824 or 1G.
  2. Avoid signs, decimals, and thousands separators.
  3. Validate with a regex like ^\d+[TtGgMmKk]?$ before launching.

Example fix

# before
--java.MaxDirectMemorySize=1G  # ok
--java.MaxDirectMemorySize=GB

# after
--java.MaxDirectMemorySize=1G
Defensive patterns

Strategy: validation

Validate before calling

if (!size.matches("\\d+[TtGgMmKk]?")) throw new ConfigException("Bad size: " + size);

Type guard

static boolean validEspressoSize(String s) { return s != null && s.matches("\\d+[TtGgMmKk]?"); }

Prevention

When it happens

Trigger: Passing --java.MaxDirectMemorySize=1G is fine, but values like 'G1', '-1g' (the converter does not accept signs), empty string, or '1.5G' (the '.' stops the digit scan only if first) fail when no digit appears at position 0.

Common situations: Reusing HotSpot -XX:MaxDirectMemorySize values with suffixes first; empty values from unset env vars; localized number formats.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/f8c4a44540eaebec. Report an issue: GitHub.