dotnet/runtime · critical · Error
posix_memalign failed for ICU data
Error message
posix_memalign failed for ICU data
What it means
Thrown by loadIcuData() (src/native/libs/Common/JavaScript/host/assets.ts:181) when _posix_memalign fails to allocate the 16-byte-aligned buffer for ICU (globalization) data. ICU data files (icudt.dat) are large, so this allocation is the one most likely to hit the heap ceiling.
Source
Thrown at src/native/libs/Common/JavaScript/host/assets.ts:186
_ems_.HEAPU32[outDataStartPtr as any >>> 2] = assembly.ptr;
// int64_t target
_ems_.HEAPU32[outSize as any >>> 2] = assembly.length;
_ems_.HEAPU32[((outSize as any) + 4) >>> 2] = 0;
return true;
}
_ems_.dotnetLogger.debug(`Assembly not found: '${path}'`);
_ems_.HEAPU32[outDataStartPtr as any >>> 2] = 0;
_ems_.HEAPU32[outSize as any >>> 2] = 0;
_ems_.HEAPU32[((outSize as any) + 4) >>> 2] = 0;
return false;
}
export function loadIcuData(bytes: Uint8Array) {
const sp = _ems_.stackSave();
try {
const ptrPtr = _ems_.stackAlloc(sizeOfPtr);
if (_ems_._posix_memalign(ptrPtr as any, 16, bytes.length)) {
throw new Error("posix_memalign failed for ICU data");
}
const ptr = _ems_.HEAPU32[ptrPtr as any >>> 2];
_ems_.HEAPU8.set(bytes, ptr >>> 0);
const result = _ems_._wasm_load_icu_data(ptr as unknown as VoidPtr);
if (!result) {
throw new Error("Failed to initialize ICU data");
}
} finally {
_ems_.stackRestore(sp);
}
}
export function installVfsFile(bytes: Uint8Array, asset: VfsAsset) {
const virtualName: string = typeof (asset.virtualPath) === "string"
? asset.virtualPath
: asset.name;View on GitHub (pinned to 60108ba66e)
Solutions
- Use a smaller ICU data file (culture-specific ICU shards / hybrid globalization) to reduce the allocation size.
- Raise the runtime maximum WebAssembly.Memory.
- Avoid loading ICU if globalization is not needed (configure globalization mode/invariant culture).
Example fix
<!-- before: full ICU loaded into small-memory runtime -->
<!-- after: ship a culture-specific ICU shard -->
<ItemGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>false</BlazorWebAssemblyLoadAllGlobalizationData>
</ItemGroup>
<!-- and/or raise memory: { "memory": { "maximum": 2048 } } --> Defensive patterns
Strategy: try-catch
Validate before calling
// pick a smaller ICU shard when memory is tight
function recommendedIcuAsset(): string {
return useHybridGlobalization ? 'icudt_hybrid.dat' : 'icudt.dat';
} Try / catch
try {
await dotnetBrowserHostExports.loadIcuData(bytes);
} catch (err) {
if (/posix_memalign failed for ICU data/.test(String((err as Error).message))) {
// switch to a culture-specific ICU shard or raise maximum memory
}
throw err;
} Prevention
- Use culture-specific or hybrid ICU shards instead of the full icudt.dat on low-memory devices.
- Raise the runtime maximum memory to accommodate ICU data.
- Skip ICU entirely if the app can run under invariant globalization.
When it happens
Trigger: fetchIcu() downloads the ICU asset, waits for the native module, then calls loadIcuData(bytes). Inside, posix_memalign(ptrPtr,16,bytes.length) returns non-zero because the heap cannot fit the ICU data blob.
Common situations: Loading the full icudt.dat into a runtime with too little maximum memory; shipping the wrong (too large) ICU shard for the app; a memory-constrained device whose maximum memory is capped low.
Related errors
- Failed to load ICU data
- Failed to initialize ICU data
- Locale or culture name is null or empty. localeName=${locale
- Locale info for locale=${localeName} is null or empty.
- invariant globalization mode is inactive and no ICU data arc
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/ad396d8f5182d5cb.
Report an issue: GitHub.