elastic/elasticsearch · error · IOException

type must be UTF-8 string

Error message

type must be UTF-8 string

What it means

Thrown by MMDBUtil.getDatabaseType when the byte immediately after the database type marker does not encode a UTF-8 string control byte. In mmdb format the high 3 bits encode the type (2 means UTF-8 string); the database_type field must be a string, so any other type indicates a corrupt or malformed metadata section. IOException surfaces during lookup wiring.

Source

Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/MMDBUtil.java:83

                    markerOffset++;
                } else {
                    markerOffset = 0;
                }
                if (markerOffset == DATABASE_TYPE_MARKER.length) {
                    metadataOffset = i + 1;
                    break;
                }
            }

            if (metadataOffset == -1) {
                throw new IOException("database type marker not found");
            }

            // read the database type
            final int offsetByte = fromBytes(tail[metadataOffset]);
            final int type = offsetByte >>> 5;
            if (type != 2) { // 2 is the type indicator in the mmdb format for a UTF-8 string
                throw new IOException("type must be UTF-8 string");
            }
            int size = offsetByte & 0x1f;
            if (size == 29) {
                // then we need to read in yet another byte and add it onto this size
                // this can actually occur in practice, a 29+ character type description isn't that hard to imagine
                size = 29 + fromBytes(tail[metadataOffset + 1]);
                metadataOffset += 1;
            } else if (size >= 30) {
                // we'd need to read two or three more bytes to get the size, but this means the type length is >=285
                throw new IOException("database_type too long [size indicator == " + size + "]");
            }

            return new String(tail, metadataOffset + 1, size, StandardCharsets.UTF_8);
        }
    }

    private static int fromBytes(byte b1) {
        return b1 & 0xFF;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Validate the file with the official mmdb tool; if it fails there too, the file is corrupt.
  2. Re-download the database to replace a corrupted copy.
  3. Confirm the file is actually an mmdb and not another binary format that happened to contain the marker bytes.
  4. If reproducible with a known-good file, capture the file for a bug report.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    String type = MMDBUtil.getDatabaseType(path);
} catch (IOException e) {
    if (e.getMessage().equals("type must be UTF-8 string")) {
        // metadata section is corrupt; re-download and revalidate with the official mmdb tool
    } else throw e;
}

Prevention

When it happens

Trigger: getDatabaseType: offsetByte = tail[metadataOffset]; type = offsetByte >>> 5; type != 2 -> throw.

Common situations: Corrupt mmdb metadata section; the marker bytes coincidentally matched inside non-metadata data of a non-mmdb file; bit-level corruption from a bad download or storage fault.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/2fe302bb91ef2a5c. Report an issue: GitHub.