nodejs/node · error

U_UNSUPPORTED_ERROR

U_UNSUPPORTED_ERROR

Error message

icupkg: data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as an ICU .dat package\n

What it means

Thrown by Package::readPackage() when the UDataInfo header's dataFormat field does not match the expected 'CmnD' (0x43, 0x6d, 0x6e, 0x44) signature with formatVersion[0]==1. This is the specific .dat package format identifier. Any other 4-byte format tag or version number means the file is not a recognized ICU .dat package.

Source

Thrown at deps/icu-small/source/tools/toolutil/package.cpp:497

    headerLength=sizeof(header);
    if(length<headerLength) {
        headerLength=length;
    }
    headerLength=udata_swapDataHeader(ds, inData, headerLength, header, &errorCode);
    if(U_FAILURE(errorCode)) {
        exit(errorCode);
    }

    /* check data format and format version */
    pInfo = reinterpret_cast<const UDataInfo*>(reinterpret_cast<const char*>(inData) + 4);
    if(!(
        pInfo->dataFormat[0]==0x43 &&   /* dataFormat="CmnD" */
        pInfo->dataFormat[1]==0x6d &&
        pInfo->dataFormat[2]==0x6e &&
        pInfo->dataFormat[3]==0x44 &&
        pInfo->formatVersion[0]==1
    )) {
        fprintf(stderr, "icupkg: data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as an ICU .dat package\n",
                pInfo->dataFormat[0], pInfo->dataFormat[1],
                pInfo->dataFormat[2], pInfo->dataFormat[3],
                pInfo->formatVersion[0]);
        exit(U_UNSUPPORTED_ERROR);
    }
    inIsBigEndian = static_cast<UBool>(pInfo->isBigEndian);
    inCharset=pInfo->charsetFamily;

    inBytes=(const uint8_t *)inData+headerLength;
    inEntries = reinterpret_cast<const UDataOffsetTOCEntry*>(inBytes + 4);

    /* check that the itemCount fits, then the ToC table, then at least the header of the last item */
    length-=headerLength;
    if(length<4) {
        /* itemCount does not fit */
        offset=0x7fffffff;
    } else {
        itemCount = udata_readInt32(ds, *reinterpret_cast<const int32_t*>(inBytes));

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure the input file is a .dat package, not an individual ICU data item.
  2. Verify the ICU version: icupkg version should match the version that created the .dat file.
  3. Inspect the header bytes: hexdump -C <file> | head -3 and check for 'CmnD' at the dataFormat offset.
  4. Rebuild the .dat package with the correct icupkg version.
Defensive patterns

Strategy: validation

Validate before calling

// Check for 'CmnD' data format tag in the .dat file header
#include <fstream>
#include <cstring>
bool isDatPackage(const char* filename) {
    std::ifstream f(filename, std::ios::binary);
    if (!f) return false;
    char buf[64];
    f.read(buf, sizeof(buf));
    if (f.gcount() < 24) return false;
    // UDataInfo.dataFormat is at offset: sizeof(headerMagic) + headerSize fields
    // Look for 'CmnD' = {0x43, 0x6d, 0x6e, 0x44} in the data
    return memmem(buf, f.gcount(), "CmnD", 4) != nullptr;
}

Prevention

When it happens

Trigger: The data header passed the initial getTypeEnumForInputData() check in readFile() (it has a valid generic ICU data header) but when readPackage() inspects the specific dataFormat field, it is not 'CmnD' version 1. This distinguishes a .dat package from other ICU data files (e.g. individual .res files, .cnv files).

Common situations: Passing an individual ICU resource file (.res), a conversion table (.cnv), or other ICU data to icupkg when it expects a .dat package; a .dat file from a much older or newer ICU version that uses a different format version; a .dat file that was post-processed or re-encoded, corrupting the format tag.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/96d04f712003ce62. Report an issue: GitHub.