{"record":{"id":"10268d5261eb47ff","repo":"elastic/elasticsearch","slug":"named-objects-are-not-supported-for-this-parser","errorCode":null,"errorMessage":"named objects are not supported for this parser","messagePattern":"named objects are not supported for this parser","errorType":"exception","errorClass":"XContentParseException","httpStatus":null,"severity":"error","filePath":"libs/x-content/src/main/java/org/elasticsearch/xcontent/NamedXContentRegistry.java","lineNumber":171,"sourceCode":"     * Returns {@code true} if this registry is able to {@link #parseNamedObject parse} the referenced object, false otherwise.\n     * Note: This method does not throw exceptions, even if the {@link RestApiVersion} or {@code categoryClass} are unknown.\n     */\n    public boolean hasParser(Class<?> categoryClass, String name, RestApiVersion apiVersion) {\n        final Map<Class<?>, Map<String, Entry>> versionMap = registry.get(apiVersion);\n        if (versionMap == null) {\n            return false;\n        }\n        final Map<String, Entry> parsers = versionMap.get(categoryClass);\n        return parsers != null && parsers.containsKey(name);\n    }\n\n    // scope for testing\n    public <T> Entry lookupParser(Class<T> categoryClass, String name, XContentParser parser) {\n        Map<String, Entry> parsers = registry.getOrDefault(parser.getRestApiVersion(), emptyMap()).get(categoryClass);\n        if (parsers == null) {\n            if (registry.isEmpty()) {\n                // The \"empty\" registry will never work so we throw a better exception as a hint.\n                throw new XContentParseException(\"named objects are not supported for this parser\");\n            }\n            throw new XContentParseException(\"unknown named object category [\" + categoryClass.getName() + \"]\");\n        }\n        Entry entry = parsers.get(name);\n        if (entry == null) {\n            throw new NamedObjectNotFoundException(parser.getTokenLocation(), \"unknown field [\" + name + \"]\", parsers.keySet());\n        }\n        if (false == entry.name.match(name, parser.getDeprecationHandler())) {\n            /* Note that this shouldn't happen because we already looked up the entry using the names but we need to call `match` anyway\n             * because it is responsible for logging deprecation warnings. */\n            throw new XContentParseException(\n                parser.getTokenLocation(),\n                \"unable to parse \" + categoryClass.getSimpleName() + \" with name [\" + name + \"]: parser didn't match\"\n            );\n        }\n        return entry;\n    }\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/x-content/src/main/java/org/elasticsearch/xcontent/NamedXContentRegistry.java#L153-L189","documentation":"NamedXContentRegistry.lookupParser throws when the registry is entirely empty (no categories registered for the active REST API version) and a named object is requested. This is a guard to give a better hint than a generic lookup miss: an empty registry (e.g. NamedXContentRegistry.EMPTY) can never resolve any named object.","triggerScenarios":"Calling parser.namedObject(...) or parsing content that references a named object while the parser was built with an empty NamedXContentRegistry. Common when constructing a parser for tests with the default/no-arg registry, or when a module that should register named content is not loaded.","commonSituations":"Test parsers using NamedXContentRegistry.EMPTY inadvertently. A plugin/module failing to register its NamedXContent entries. Misconfigured parser factory that drops the registry.","solutions":["Build the parser with a non-empty NamedXContentRegistry containing the required category/name entries (e.g. the cluster's getNamedXContentRegistry()).","Ensure modules/plugins contributing named content are loaded so the registry is populated before parsing.","In tests, construct a NamedXContentRegistry with the minimal List<Entry> needed rather than using EMPTY."],"exampleFix":"// before\nXContentParser p = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, in);\n\n// after\nNamedXContentRegistry reg = new NamedXContentRegistry(List.of(\n    new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(\"my_agg\"), p -> ...)));\nXContentParser p = XContentType.JSON.xContent().createParser(reg, in);","handlingStrategy":"validation","validationCode":"// before parsing named content, ensure the registry is non-empty and has the category\nif (registry.isEmpty()) {\n    registry = buildRegistryWithKnownCategories(); // never pass EMPTY for named content\n}","typeGuard":null,"tryCatchPattern":"try {\n    p.parse(parser, ctx);\n} catch (XContentParseException e) {\n    if (e.getMessage().equals(\"named objects are not supported for this parser\")) {\n        // rebuild parser with a populated NamedXContentRegistry\n    }\n}","preventionTips":["Never construct named-content parsers with NamedXContentRegistry.EMPTY; use the cluster's registry.","In tests, build a NamedXContentRegistry from an explicit Entry list covering the categories under test.","Assert the registry contains expected categories at parser-construction time."],"tags":["xcontent","named-content","registry","deserialization"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}