nodejs/node · error

U_INVALID_FORMAT_ERROR

U_INVALID_FORMAT_ERROR

Error message

icupkg: not an ICU data file: \"%s\"\n

What it means

Thrown by readFile() when getTypeEnumForInputData() returns a negative value or sets a failure UErrorCode after inspecting the file's header. This means the data does not have a valid ICU data header (magic bytes, UDataInfo structure) for any recognized charset/endian combination.

Source

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

    /* read the file */
    if (fileLength != static_cast<int32_t>(fread(data.getAlias(), 1, fileLength, file))) {
        fprintf(stderr, "icupkg: error reading \"%s\"\n", filename);
        fclose(file);
        exit(U_FILE_ACCESS_ERROR);
    }

    /* pad the file to a multiple of 16 using the usual padding byte */
    if(fileLength<length) {
        memset(data.getAlias()+fileLength, 0xaa, length-fileLength);
    }

    fclose(file);

    // minimum check for ICU-format data
    errorCode=U_ZERO_ERROR;
    typeEnum=getTypeEnumForInputData(data.getAlias(), length, &errorCode);
    if(typeEnum<0 || U_FAILURE(errorCode)) {
        fprintf(stderr, "icupkg: not an ICU data file: \"%s\"\n", filename);
#if !UCONFIG_NO_LEGACY_CONVERSION
        exit(U_INVALID_FORMAT_ERROR);
#else
        fprintf(stderr, "U_INVALID_FORMAT_ERROR occurred but UCONFIG_NO_LEGACY_CONVERSION is on so this is expected.\n");
        exit(0);
#endif
    }
    type=makeTypeLetter(typeEnum);

    return data.orphan();
}

// .dat package file representation ---------------------------------------- ***

U_CDECL_BEGIN

static int32_t U_CALLCONV
compareItems(const void * /*context*/, const void *left, const void *right) {

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Verify the file is actually an ICU data file: hexdump -C <file> | head and look for the ICU magic header.
  2. Re-download or rebuild the data file from a trusted source.
  3. Ensure binary-safe transfer: use scp or rsync, not FTP text mode.
  4. Check the ICU version compatibility between the data file and the icupkg tool version.

Example fix

// verify the file header
// before: random file passed as .dat
icupkg unknown_file.dat
// after: use the correct ICU data file
icupkg icudt62l.dat
Defensive patterns

Strategy: validation

Validate before calling

// Check for ICU data header magic bytes before processing
#include <fstream>
#include <cstring>
bool hasValidICUHeader(const char* filename) {
    std::ifstream f(filename, std::ios::binary);
    if (!f) return false;
    char buf[32];
    f.read(buf, sizeof(buf));
    if (f.gcount() < 16) return false;
    // Check for ICU data header magic (0xda 0x27 or similar in header)
    uint16_t magic = *reinterpret_cast<uint16_t*>(buf + 0);
    return magic == 0xda; // ICU data magic
}

Prevention

When it happens

Trigger: Passing a non-ICU binary file as input to icupkg, or a corrupted/truncated ICU data file whose header bytes are invalid. getTypeEnumForInputData() inspects the data header to determine charset family and endianness; if it cannot, the file is rejected as not an ICU data file.

Common situations: Wrong file passed to icupkg (e.g. a .so, .exe, or arbitrary binary instead of an ICU .dat or item file); a .dat file that was downloaded incorrectly (HTML error page saved as .dat); a file corrupted by transfer (FTP text mode, encoding conversion); a file from a future or incompatible ICU version with a different header format.

Related errors


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