nodejs/node · error

icupkg: udata_openSwapper(\"%s\") failed - %s\n

Error message

icupkg: udata_openSwapper(\"%s\") failed - %s\n

What it means

When an item's endianness/charset differs from the host, pkgitems calls udata_openSwapper to byte-swap it; if that fails the item name + u_errorName are printed and exit(errorCode). The swap is needed because the .dat being extracted contains cross-endian/charset data.

Source

Thrown at deps/icu-small/source/tools/toolutil/pkgitems.cpp:95

        return length;
    }

    void setItem(const Item *item, UDataSwapFn *swap) {
        pItem=item;
        int32_t infoLength, itemHeaderLength;
        UErrorCode errorCode=U_ZERO_ERROR;
        pInfo=::getDataInfo(pItem->data, pItem->length, infoLength, itemHeaderLength, &errorCode);
        if(U_FAILURE(errorCode)) {
            exit(errorCode); // should succeed because readFile() checks headers
        }
        length=pItem->length-itemHeaderLength;

        if(pInfo->isBigEndian==U_IS_BIG_ENDIAN && pInfo->charsetFamily==U_CHARSET_FAMILY) {
            bytes=pItem->data+itemHeaderLength;
        } else {
            UDataSwapper* ds = udata_openSwapper(static_cast<UBool>(pInfo->isBigEndian), pInfo->charsetFamily, U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode);
            if(U_FAILURE(errorCode)) {
                fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n",
                        pItem->name, u_errorName(errorCode));
                exit(errorCode);
            }

            ds->printError=printError;
            ds->printErrorContext=stderr;

            swapped=new uint8_t[pItem->length];
            if(swapped==nullptr) {
                fprintf(stderr, "icupkg: unable to allocate memory for swapping \"%s\"\n", pItem->name);
                exit(U_MEMORY_ALLOCATION_ERROR);
            }
            swap(ds, pItem->data, pItem->length, swapped, &errorCode);
            pInfo=::getDataInfo(swapped, pItem->length, infoLength, itemHeaderLength, &errorCode);
            bytes=swapped+itemHeaderLength;
            udata_closeSwapper(ds);
        }
    }

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Regenerate the .dat from source data with a matching/current ICU build.
  2. Verify the .dat header bytes (magic, endianness, charsetFamily) are valid before extracting.
  3. Do not mix .dat files across incompatible ICU major versions; rebuild from source.
  4. Run icupkg -l (list) to inspect the package integrity before operating on items.

Example fix

# before: extracting from a corrupt/cross-endian .dat
icupkg -x bad.dat
# after
icupkg -l good.dat            # confirm header is sane first
icupkg -tb good.dat out.dat   # rebuild with host endianness
Defensive patterns

Strategy: validation

Validate before calling

# inspect package integrity and header before extracting/swapping
icupkg -l "$DAT" >/dev/null || { echo "package header invalid" >&2; exit 1; }
# rebuild cross-endian .dat from source rather than trusting unknown files

Prevention

When it happens

Trigger: A .dat item whose data header declares an endianness/charsetFamily that udata_openSwapper rejects (invalid combination, or a corrupt header). The guard `if(U_FAILURE(errorCode))` after udata_openSwapper fires.

Common situations: Corrupt or hand-edited ICU .dat where the header's isBigEndian/charsetFamily bytes are invalid; a .dat produced by an incompatible/very old ICU version; truncation damaging the header.

Related errors


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