{"record":{"id":"f9bbf2c7e9b94178","repo":"nodejs/node","slug":"u-memory-allocation-error-f9bbf2","errorCode":"U_MEMORY_ALLOCATION_ERROR","errorMessage":"icupkg: malloc error allocating %d bytes.\\n","messagePattern":"icupkg: malloc error allocating (.+?) bytes\\.\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"deps/icu-small/source/tools/toolutil/package.cpp","lineNumber":334,"sourceCode":"    if(file==nullptr) {\n        fprintf(stderr, \"icupkg: unable to open input file \\\"%s\\\"\\n\", filename);\n        exit(U_FILE_ACCESS_ERROR);\n    }\n\n    /* get the file length */\n    fileLength=getFileLength(file);\n    if(ferror(file) || fileLength<=0) {\n        fprintf(stderr, \"icupkg: empty input file \\\"%s\\\"\\n\", filename);\n        fclose(file);\n        exit(U_FILE_ACCESS_ERROR);\n    }\n\n    /* allocate the buffer, pad to multiple of 16 */\n    length=(fileLength+0xf)&~0xf;\n    icu::LocalMemory<uint8_t> data(static_cast<uint8_t*>(uprv_malloc(length)));\n    if(data.isNull()) {\n        fclose(file);\n        fprintf(stderr, \"icupkg: malloc error allocating %d bytes.\\n\", static_cast<int>(length));\n        exit(U_MEMORY_ALLOCATION_ERROR);\n    }\n\n    /* read the file */\n    if (fileLength != static_cast<int32_t>(fread(data.getAlias(), 1, fileLength, file))) {\n        fprintf(stderr, \"icupkg: error reading \\\"%s\\\"\\n\", filename);\n        fclose(file);\n        exit(U_FILE_ACCESS_ERROR);\n    }\n\n    /* pad the file to a multiple of 16 using the usual padding byte */\n    if(fileLength<length) {\n        memset(data.getAlias()+fileLength, 0xaa, length-fileLength);\n    }\n\n    fclose(file);\n\n    // minimum check for ICU-format data","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/package.cpp#L316-L352","documentation":"Thrown by readFile() when uprv_malloc() returns NULL while allocating a buffer for reading a data file. The allocation size is the file length padded up to a multiple of 16 bytes. This indicates the system cannot satisfy the memory request.","triggerScenarios":"Reading a data file whose padded length causes uprv_malloc() to fail. This can happen with very large data files, or when system memory is exhausted. The padded length is (fileLength + 0xf) & ~0xf.","commonSituations":"Very large ICU data files that exceed available virtual memory; process memory limits (ulimit -v) in CI environments; containers with low memory cgroup limits; 32-bit processes with limited address space; memory fragmentation after many allocations.","solutions":["Check available memory: free -h and ulimit -v.","If running in a container, increase the memory limit.","Reduce the data file size by trimming unnecessary locales with icupkg -r before processing.","Build with a 64-bit toolchain if currently 32-bit."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check available memory and file size before processing\n#include <sys/stat.h>\n#include <sys/resource.h>\nbool canAllocateForFile(const char* filename) {\n    struct stat st;\n    if (stat(filename, &st) != 0) return false;\n    size_t needed = (st.st_size + 0xf) & ~0xf; // pad to 16\n    struct rlimit rl;\n    if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {\n        return needed < rl.rlim_cur / 4; // conservative heuristic\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Monitor memory usage in CI and build containers.","Set appropriate container memory limits higher than the largest expected .dat file.","Use 64-bit builds for large data packages.","Trim unnecessary locales with icupkg -r to reduce data size."],"tags":["icu","icupkg","memory","oom","malloc","allocation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}