nodejs/node · error

U_INDEX_OUTOFBOUNDS_ERROR

U_INDEX_OUTOFBOUNDS_ERROR

Error message

icupkg: too few bytes (%ld after header) for a .dat package\n

What it means

Thrown by Package::readPackage() when the remaining data after the header (length - headerLength) is less than the computed minimum offset. The minimum offset is the larger of: the space needed for the item count int32, the full ToC table (4 + 8*itemCount bytes), or the last item's data offset plus 20 bytes for its header. This means the file is truncated relative to what its ToC claims.

Source

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

    length-=headerLength;
    if(length<4) {
        /* itemCount does not fit */
        offset=0x7fffffff;
    } else {
        itemCount = udata_readInt32(ds, *reinterpret_cast<const int32_t*>(inBytes));
        setItemCapacity(itemCount); /* resize so there's space */
        if(itemCount==0) {
            offset=4;
        } else if(length<(4+8*itemCount)) {
            /* ToC table does not fit */
            offset=0x7fffffff;
        } else {
            /* offset of the last item plus at least 20 bytes for its header */
            offset = 20 + static_cast<int32_t>(ds->readUInt32(inEntries[itemCount - 1].dataOffset));
        }
    }
    if(length<offset) {
        fprintf(stderr, "icupkg: too few bytes (%ld after header) for a .dat package\n",
                        static_cast<long>(length));
        exit(U_INDEX_OUTOFBOUNDS_ERROR);
    }
    /* do not modify the package length variable until the last item's length is set */

    if(itemCount<=0) {
        if(doAutoPrefix) {
            fprintf(stderr, "icupkg: --auto_toc_prefix[_with_type] but the input package is empty\n");
            exit(U_INVALID_FORMAT_ERROR);
        }
    } else {
        char prefix[MAX_PKG_NAME_LENGTH+4];
        char *s, *inItemStrings;

        if(itemCount>itemMax) {
            fprintf(stderr, "icupkg: too many items, maximum is %d\n", itemMax);
            exit(U_BUFFER_OVERFLOW_ERROR);
        }

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Verify file integrity: compare file size against expected size from the build system.
  2. Re-download or rebuild the .dat file.
  3. Check the file is not truncated: ls -l and compare against a known-good copy.
  4. If modifying .dat files, use icupkg itself rather than manual binary editing.
Defensive patterns

Strategy: validation

Validate before calling

// Verify file size is plausible for a .dat package
#include <sys/stat.h>
#include <fstream>
bool isPlausibleDatSize(const char* filename) {
    struct stat st;
    if (stat(filename, &st) != 0) return false;
    // A valid .dat must have at least a header + 4 bytes for item count
    if (st.st_size < 32) return false;
    // Read item count and check ToC plausibility
    std::ifstream f(filename, std::ios::binary);
    f.seekg(20); // approximate offset past header
    int32_t itemCount = 0;
    f.read(reinterpret_cast<char*>(&itemCount), 4);
    // ToC must fit: 4 + 8*itemCount < remaining file
    return itemCount >= 0 && (4 + 8 * static_cast<int64_t>(itemCount)) < st.st_size;
}

Prevention

When it happens

Trigger: A .dat file whose header and ToC entries describe more data than the file actually contains. Specifically: length < 4 (no item count), or length < 4+8*itemCount (ToC table incomplete), or length < 20+lastItemDataOffset (last item header missing). The offset is set to 0x7fffffff (effectively infinite) when the ToC cannot fit, guaranteeing the check fails.

Common situations: Truncated .dat files from interrupted builds or incomplete downloads; corrupt ToC entries with inflated dataOffset values; manual editing of binary .dat files that changed the structure without updating offsets; filesystem corruption.

Related errors


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