dotnet/runtime · critical

max-heap-size must be an integer.\n

Error message

max-heap-size must be an integer.\n

What it means

Emitted during Mono Boehm GC init in mono_gc_base_init (boehm-gc.c:176) when a `max-heap-size=` token is present but mono_gc_parse_environment_string_extract_number returns FALSE. That helper fails on an empty string, a non-digit last character that is not a valid k/m/g suffix, strtol overflow (ERANGE), or a suffix form with trailing characters after the suffix. On failure the runtime prints 'max-heap-size must be an integer.' and calls exit(1), killing the process at GC init before managed code runs.

Source

Thrown at src/mono/mono/metadata/boehm-gc.c:176

	GC_init_gcj_malloc (5, NULL);
	GC_allow_register_threads ();

	if ((env = g_getenv ("MONO_GC_PARAMS"))) {
		char **ptr, **opts = g_strsplit (env, ",", -1);
		for (ptr = opts; *ptr; ++ptr) {
			char *opt = *ptr;
			if (g_str_has_prefix (opt, "max-heap-size=")) {
				size_t max_heap;

				opt = strchr (opt, '=') + 1;
				if (*opt && mono_gc_parse_environment_string_extract_number (opt, &max_heap)) {
					if (max_heap < MIN_BOEHM_MAX_HEAP_SIZE) {
						fprintf (stderr, "max-heap-size must be at least %dMb.\n", MIN_BOEHM_MAX_HEAP_SIZE_IN_MB);
						exit (1);
					}
					GC_set_max_heap_size (max_heap);
				} else {
					fprintf (stderr, "max-heap-size must be an integer.\n");
					exit (1);
				}
				continue;
			} else if (g_str_has_prefix (opt, "toggleref-test")) {
				register_test_toggleref_callback ();
				continue;
			} else {
				/* Could be a parameter for sgen */
				/*
				fprintf (stderr, "MONO_GC_PARAMS must be a comma-delimited list of one or more of the following:\n");
				fprintf (stderr, "  max-heap-size=N (where N is an integer, possibly with a k, m or a g suffix)\n");
				exit (1);
				*/
			}
		}
		g_free (env);
		g_strfreev (opts);
	}

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Use a plain integer or a single k/m/g suffix: MONO_GC_PARAMS=max-heap-size=256m (not 256mb / 256MB).
  2. Remove any trailing unit characters, spaces, or quotes; the token after '=' must be digits optionally followed by exactly one of k/m/g (case-insensitive).
  3. For very large values, drop down a suffix to avoid size_t overflow (e.g. prefer 4g over 4294967296).
  4. Validate MONO_GC_PARAMS in a launch wrapper (parse the same way) before starting Mono so misconfigurations fail with your own message.
  5. Inspect for accidental empty assignments from CI/CD templating (e.g. MONO_GC_PARAMS=max-heap-size=$HEAP where $HEAP is unset).

Example fix

# before
$ MONO_GC_PARAMS=max-heap-size=256mb mono app.exe   # 'mb' is invalid
max-heap-size must be an integer.
# (process exits)

# after
$ MONO_GC_PARAMS=max-heap-size=256m mono app.exe
Defensive patterns

Strategy: validation

Validate before calling

# Validate max-heap-size syntax (digits + optional single k/m/g) exactly as mono_gc_parse_environment_string_extract_number does.
python3 - <<'PY'
import os, re
for tok in os.environ.get('MONO_GC_PARAMS','').split(','):
    m = re.match(r'^max-heap-size=(.*)$', tok.strip())
    if not m: continue
    val = m.group(1)
    if not re.match(r'^\d+[kKmMgG]?$', val):
        raise SystemExit(f'ERROR: max-heap-size={val!r} is not <integer>[k|m|g]; use e.g. 256m')
print('MONO_GC_PARAMS OK')
PY
exec mono "$@"

Prevention

When it happens

Trigger: Boehm-GC Mono runtime started with MONO_GC_PARAMS=max-heap-size=<bad>, where <bad> is empty (max-heap-size=), non-numeric (max-heap-size=abc), contains trailing garbage (max-heap-size=64mb, max-heap-size=10x), uses an unsupported suffix (max-heap-size=64b), or overflows size_t. The parser in parse.c:28 rejects all of these and returns FALSE, tripping the else-branch fprintf at boehm-gc.c:176.

Common situations: Writing 'mb'/'MB' instead of 'm' (the helper only accepts a single m/M/k/K/g/G); a stray space or unit; an empty value from a templated env file; copy-pasting a Java -Xmx style value; value too large for the platform size_t (ERANGE); shell-quoting dropping the number.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/123096d03cf7da40. Report an issue: GitHub.