{"record":{"id":"123096d03cf7da40","repo":"dotnet/runtime","slug":"max-heap-size-must-be-an-integer-n","errorCode":null,"errorMessage":"max-heap-size must be an integer.\\n","messagePattern":"max-heap-size must be an integer\\.\\\\n","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/mono/mono/metadata/boehm-gc.c","lineNumber":176,"sourceCode":"\tGC_init_gcj_malloc (5, NULL);\n\tGC_allow_register_threads ();\n\n\tif ((env = g_getenv (\"MONO_GC_PARAMS\"))) {\n\t\tchar **ptr, **opts = g_strsplit (env, \",\", -1);\n\t\tfor (ptr = opts; *ptr; ++ptr) {\n\t\t\tchar *opt = *ptr;\n\t\t\tif (g_str_has_prefix (opt, \"max-heap-size=\")) {\n\t\t\t\tsize_t max_heap;\n\n\t\t\t\topt = strchr (opt, '=') + 1;\n\t\t\t\tif (*opt && mono_gc_parse_environment_string_extract_number (opt, &max_heap)) {\n\t\t\t\t\tif (max_heap < MIN_BOEHM_MAX_HEAP_SIZE) {\n\t\t\t\t\t\tfprintf (stderr, \"max-heap-size must be at least %dMb.\\n\", MIN_BOEHM_MAX_HEAP_SIZE_IN_MB);\n\t\t\t\t\t\texit (1);\n\t\t\t\t\t}\n\t\t\t\t\tGC_set_max_heap_size (max_heap);\n\t\t\t\t} else {\n\t\t\t\t\tfprintf (stderr, \"max-heap-size must be an integer.\\n\");\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t} else if (g_str_has_prefix (opt, \"toggleref-test\")) {\n\t\t\t\tregister_test_toggleref_callback ();\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t/* Could be a parameter for sgen */\n\t\t\t\t/*\n\t\t\t\tfprintf (stderr, \"MONO_GC_PARAMS must be a comma-delimited list of one or more of the following:\\n\");\n\t\t\t\tfprintf (stderr, \"  max-heap-size=N (where N is an integer, possibly with a k, m or a g suffix)\\n\");\n\t\t\t\texit (1);\n\t\t\t\t*/\n\t\t\t}\n\t\t}\n\t\tg_free (env);\n\t\tg_strfreev (opts);\n\t}","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/mono/metadata/boehm-gc.c#L158-L194","documentation":"Emitted by Mono's Boehm GC backend in mono_gc_base_init while parsing the MONO_GC_PARAMS environment variable. The 'max-heap-size=' value is parsed with mono_gc_parse_environment_string_extract_number, which accepts only digits with an optional single trailing k/m/g suffix. When parsing fails, the runtime prints this message and calls exit(1), aborting startup before the app runs. Note this fatal-exit path is specific to Boehm; SGen has an analogous check (sgen-gc.c:3561) that only logs via sgen_env_var_error and continues.","triggerScenarios":"Setting MONO_GC_PARAMS with 'max-heap-size=<X>' where <X> is empty, contains non-digit characters (other than a single trailing k/m/g), has trailing garbage after the suffix (e.g. '512mib'), or overflows strtol/size_t. The value is also rejected with a different message if below MIN_BOEHM_MAX_HEAP_SIZE_IN_MB (16 MB).","commonSituations":"Shell scripts that interpolate an unset variable (max-heap-size=$HEAP with HEAP empty), copy-pasting documentation that spells units as 'mb' instead of 'm', a stray comma or quote inside the value, or a typo such as 'max-heap-size=512MB'. Occurs on startup of any Mono process using the Boehm collector.","solutions":["Set the value to a plain integer or integer plus a single k/m/g suffix, e.g. MONO_GC_PARAMS=max-heap-size=512m","If the value is interpolated from another variable, guard against emptiness, e.g. ${HEAP:-256m}","Confirm the resolved value is >= 16 MB to avoid the separate 'must be at least 16Mb' fatal check","If you intended to configure SGen instead of Boehm, verify which collector is active; this exit(1) only fires under Boehm"],"exampleFix":"# before\nexport MONO_GC_PARAMS=max-heap-size=$HEAP   # aborts when HEAP is unset/empty\n\n# after\nexport MONO_GC_PARAMS=max-heap-size=${HEAP:-512m}","handlingStrategy":"validation","validationCode":"# Validate MONO_GC_PARAMS max-heap-size BEFORE launching mono.\n# Accepts digits with an optional single trailing k/m/g; rejects empty/garbage.\nvalidate_max_heap () {\n  local val=\"$1\"\n  if [[ ! \"$val\" =~ ^[0-9]+[kKmMgG]?$ ]]; then\n    echo \"reject: '$val' is not an integer (optional k/m/g suffix)\" >&2\n    return 1\n  fi\n  # numeric part must be >= 16 (MB floor) when given as plain megabytes\n  local num=\"${val%[kKmMgG]}\"\n  if [[ \"$val\" =~ [gG]$ ]]; then num=$((num*1024));\n  elif [[ \"$val\" =~ [kK]$ ]]; then num=$((num/1024)); fi\n  (( num >= 16 )) || { echo \"reject: below 16MB floor\" >&2; return 1; }\n  return 0\n}\n# usage: validate_max_heap \"${HEAP:-}\" && export MONO_GC_PARAMS=max-heap-size=$HEAP","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never interpolate an unguarded variable into MONO_GC_PARAMS; default it, e.g. ${HEAP:-512m}","Treat the value as a pure integer plus at most one k/m/g letter (lowercase preferred); 'mb', 'mib', spaces, and quotes are invalid","Remember the floor is 16 MB on Boehm and the failure mode is process exit(1), not an exception","In launch scripts, run the validator above before exec'ing the mono runtime so misconfiguration fails fast with a clear message"],"tags":["mono","gc","boehm-gc","configuration","environment-variable","startup"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}