{"record":{"id":"2fe302bb91ef2a5c","repo":"elastic/elasticsearch","slug":"type-must-be-utf-8-string","errorCode":null,"errorMessage":"type must be UTF-8 string","messagePattern":"type must be UTF-8 string","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/MMDBUtil.java","lineNumber":83,"sourceCode":"                    markerOffset++;\n                } else {\n                    markerOffset = 0;\n                }\n                if (markerOffset == DATABASE_TYPE_MARKER.length) {\n                    metadataOffset = i + 1;\n                    break;\n                }\n            }\n\n            if (metadataOffset == -1) {\n                throw new IOException(\"database type marker not found\");\n            }\n\n            // read the database type\n            final int offsetByte = fromBytes(tail[metadataOffset]);\n            final int type = offsetByte >>> 5;\n            if (type != 2) { // 2 is the type indicator in the mmdb format for a UTF-8 string\n                throw new IOException(\"type must be UTF-8 string\");\n            }\n            int size = offsetByte & 0x1f;\n            if (size == 29) {\n                // then we need to read in yet another byte and add it onto this size\n                // this can actually occur in practice, a 29+ character type description isn't that hard to imagine\n                size = 29 + fromBytes(tail[metadataOffset + 1]);\n                metadataOffset += 1;\n            } else if (size >= 30) {\n                // we'd need to read two or three more bytes to get the size, but this means the type length is >=285\n                throw new IOException(\"database_type too long [size indicator == \" + size + \"]\");\n            }\n\n            return new String(tail, metadataOffset + 1, size, StandardCharsets.UTF_8);\n        }\n    }\n\n    private static int fromBytes(byte b1) {\n        return b1 & 0xFF;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/MMDBUtil.java#L65-L101","documentation":"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.","triggerScenarios":"getDatabaseType: offsetByte = tail[metadataOffset]; type = offsetByte >>> 5; type != 2 -> throw.","commonSituations":"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.","solutions":["Validate the file with the official mmdb tool; if it fails there too, the file is corrupt.","Re-download the database to replace a corrupted copy.","Confirm the file is actually an mmdb and not another binary format that happened to contain the marker bytes.","If reproducible with a known-good file, capture the file for a bug report."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    String type = MMDBUtil.getDatabaseType(path);\n} catch (IOException e) {\n    if (e.getMessage().equals(\"type must be UTF-8 string\")) {\n        // metadata section is corrupt; re-download and revalidate with the official mmdb tool\n    } else throw e;\n}","preventionTips":["Validate mmdb files with the official tool before loading.","Re-download on corruption rather than retrying the same file.","Confirm the file is genuinely mmdb and not a coincidental marker match in another format.","Capture the file for analysis if corruption is reproducible."],"tags":["geoip","mmdb","metadata","data-integrity","corruption"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}