{"record":{"id":"f1bdcfcbc8f766de","repo":"dotnet/runtime","slug":"invariant-globalization-mode-is-inactive-and-no-ic","errorCode":null,"errorMessage":"invariant globalization mode is inactive and no ICU data archives are available","messagePattern":"invariant globalization mode is inactive and no ICU data archives are available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/loader/icu.ts","lineNumber":23,"sourceCode":"import { GlobalizationMode, MonoConfig } from \"../types\";\nimport { ENVIRONMENT_IS_WEB, loaderHelpers } from \"./globals\";\nimport { mono_log_info, mono_log_debug } from \"./logging\";\n\nexport function init_globalization () {\n    loaderHelpers.preferredIcuAsset = getIcuResourceName(loaderHelpers.config);\n    let invariantMode = loaderHelpers.config.globalizationMode == GlobalizationMode.Invariant;\n\n    if (!invariantMode) {\n        if (loaderHelpers.preferredIcuAsset) {\n            mono_log_debug(\"ICU data archive(s) available, disabling invariant mode\");\n        } else if (loaderHelpers.config.globalizationMode !== GlobalizationMode.Custom && loaderHelpers.config.globalizationMode !== GlobalizationMode.All && loaderHelpers.config.globalizationMode !== GlobalizationMode.Sharded) {\n            mono_log_debug(\"ICU data archive(s) not available, using invariant globalization mode\");\n            invariantMode = true;\n            loaderHelpers.preferredIcuAsset = null;\n        } else {\n            const msg = \"invariant globalization mode is inactive and no ICU data archives are available\";\n            mono_log_error(`ERROR: ${msg}`);\n            throw new Error(msg);\n        }\n    }\n\n    const invariantEnv = \"DOTNET_SYSTEM_GLOBALIZATION_INVARIANT\";\n    const env_variables = loaderHelpers.config.environmentVariables!;\n    if (env_variables[invariantEnv] === undefined && invariantMode) {\n        env_variables[invariantEnv] = \"1\";\n    }\n    if (env_variables[\"TZ\"] === undefined) {\n        try {\n            // this call is relatively expensive, so we call it during download of other assets\n            const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || null;\n            if (timezone) {\n                env_variables![\"TZ\"] = timezone;\n            }\n        } catch {\n            mono_log_info(\"failed to detect timezone, will fallback to UTC\");\n        }","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/loader/icu.ts#L5-L41","documentation":"init_globalization throws when globalizationMode is set to a non-invariant mode (sharded, all, or custom) but no ICU data archive could be resolved, so preferredIcuAsset is null. The loader only auto-falls-back to invariant for the undefined/auto modes; an explicit sharded/all/custom request with missing ICU data is treated as a hard failure because culture APIs would be broken.","triggerScenarios":"config.globalizationMode is 'sharded', 'all', or 'custom' but config.resources.icu is empty or the expected file (icudt.dat / the sharded icudt_EFIGS.dat|icudt_CJK.dat|icudt_no_CJK.dat / a custom file) is absent, so getIcuResourceName returns null and the else-branch in init_globalization fires.","commonSituations":"Setting <InvariantGlobalization>true</InvariantGlobalization> in the project while a runtime config still requests sharded/all ICU; publishing with trimmed resources so icudt*.dat is stripped; a custom ICU file path that does not resolve; upgrading versions where ICU asset naming or sharding changed.","solutions":["If you do not need culture data: set globalizationMode to 'invariant' (or InvariantGlobalization=true) and republish so the runtime uses the invariant fallback.","If you need globalization: remove InvariantGlobalization, keep globalizationMode at sharded/all/custom, and verify the icudt*.dat file appears under _framework/ and is listed in the generated mono-config's resources.icu.","For custom mode, confirm the custom ICU file is present in resources and its name matches getIcuResourceName's first-entry selection."],"exampleFix":"// before: config globalizationMode 'sharded' but no icu asset shipped\n// mono-config.json\n\"globalizationMode\": \"sharded\"\n// after\n\"globalizationMode\": \"invariant\"","handlingStrategy":"validation","validationCode":"// Inspect the generated mono-config before startup to confirm ICU assets exist for the requested mode.\nconst cfg = monoConfig; // the config object passed to the runtime\nconst mode = cfg.globalizationMode;\nconst hasIcu = Array.isArray(cfg.resources?.icu) && cfg.resources.icu.length > 0;\nif ((mode === 'sharded' || mode === 'all' || mode === 'custom') && !hasIcu) {\n  throw new Error(`globalizationMode '${mode}' requires ICU data that is missing; use 'invariant' or ship icudt assets.`);\n}","typeGuard":null,"tryCatchPattern":"// init_globalization runs during create(); catch and fall back to invariant.\ntry {\n  await dotnet.create();\n} catch (e) {\n  if (String(e?.message).includes('no ICU data archives are available')) {\n    config.globalizationMode = 'invariant';\n    await dotnet.create(); // retry with invariant\n  } else throw e;\n}","preventionTips":["Decide globalization needs up front: either enable InvariantGlobalization or ensure icudt assets are published.","After publish, verify icudt*.dat exists under _framework/ and is listed in the mono config resources.icu.","Do not mix <InvariantGlobalization>true</InvariantGlobalization> with a runtime config requesting sharded/all ICU."],"tags":["globalization","icu","configuration","startup"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}