nodejs/node · error

udata_openSwapperForInputData(pool bundle %s) failed: %s

Error message

udata_openSwapperForInputData(pool bundle %s) failed: %s

What it means

udata_openSwapperForInputData() failed on the pool bundle bytes. The swapper normalizes endianness and charset family so a single checked-in pool.res can be consumed on any platform; failure means the bytes do not look like a valid ICU data file, the magic/header is wrong, or the requested U_IS_BIG_ENDIAN / U_CHARSET_FAMILY combination is unsupported. The actual error code is printed via u_errorName.

Source

Thrown at deps/icu-small/source/tools/genrb/genrb.cpp:403

            return U_MEMORY_ALLOCATION_ERROR;
        }

        UDataSwapper *ds;
        const DataHeader *header;
        int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, poolFileSize);
        if (bytesRead != poolFileSize) {
            fprintf(stderr, "unable to read the pool bundle file %s\n", poolFileName.data());
            return 1;
        }
        /*
         * Swap the pool bundle so that a single checked-in file can be used.
         * The swapper functions also test that the data looks like
         * a well-formed .res file.
         */
        ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead,
                                           U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &status);
        if (U_FAILURE(status)) {
            fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) failed: %s\n",
                    poolFileName.data(), u_errorName(status));
            return status;
        }
        ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &status);
        udata_closeSwapper(ds);
        if (U_FAILURE(status)) {
            fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n",
                    poolFileName.data(), u_errorName(status));
            return status;
        }
        header = reinterpret_cast<const DataHeader*>(poolBundle.fBytes);
        if (header->info.formatVersion[0] < 2) {
            fprintf(stderr, "invalid format of pool bundle file %s\n", poolFileName.data());
            return U_INVALID_FORMAT_ERROR;
        }
        const int32_t* pRoot = reinterpret_cast<const int32_t*>(
                reinterpret_cast<const char*>(header) + header->dataHeader.headerSize);
        poolBundle.fIndexes = pRoot + 1;

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Regenerate pool.res using the same ICU version (and same endianness/charset target) as the consuming genrb.
  2. Inspect the printed u_errorName (e.g. U_INVALID_FORMAT_ERROR) to confirm the file is malformed.
  3. Do not mix pool.res files across ICU major versions.
Defensive patterns

Strategy: validation

Validate before calling

# Validate pool.res is a real ICU data file before using it
if command -v icupkg >/dev/null 2>&1; then
  icupkg -l "$POOL_DIR/pool.res" >/dev/null || { echo "pool.res is not a valid ICU data file" >&2; exit 2; }
fi

Try / catch

genrb --usePoolBundle "$POOL_DIR" "$@" 2>err.log || {
  grep -q 'udata_openSwapperForInputData' err.log && \
    echo "pool.res rejected by swapper; regenerate with matching ICU version/endian" >&2
  exit 1
}

Prevention

When it happens

Trigger: Feeding a non-.res file as pool.res; a pool.res built by an incompatible ICU version whose data header the swapper rejects; bit-rot or truncation that breaks the header.

Common situations: Cross-building ICU data on one endianness/charset and consuming on another with an incompatible pool.res; reusing a pool.res from a different ICU major version.

Related errors


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