{"record":{"id":"33cfbd9c7b465213","repo":"apache/pulsar","slug":"can-t-get-accurate-schema-information-for-topic","errorCode":null,"errorMessage":"Can't get accurate schema information for topic ${topicName}using AutoConsumeSchema because SchemaInfoProvider is not set yet","messagePattern":"Can't get accurate schema information for topic (.+?)using AutoConsumeSchema because SchemaInfoProvider is not set yet","errorType":"exception","errorClass":"SchemaSerializationException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/AutoConsumeSchema.java","lineNumber":341,"sourceCode":"     * @see #atSchemaVersion(byte[])\n     */\n    public Schema<?> unwrapInternalSchema(byte[] schemaVersion) {\n        fetchSchemaIfNeeded(BytesSchemaVersion.of(schemaVersion));\n        return getInternalSchema(schemaVersion);\n    }\n\n    /**\n     * It may happen that the schema is not loaded but we need it, for instance in order to call getSchemaInfo()\n     * We cannot call this method in getSchemaInfo, because getSchemaInfo is called in many\n     * places and we will introduce lots of deadlocks.\n     */\n    public void fetchSchemaIfNeeded(SchemaVersion schemaVersion) throws SchemaSerializationException {\n        if (schemaVersion == null) {\n            schemaVersion = BytesSchemaVersion.of(new byte[0]);\n        }\n        if (!schemaMap.containsKey(schemaVersion)) {\n            if (schemaInfoProvider == null) {\n                throw new SchemaSerializationException(\"Can't get accurate schema information for topic \" + topicName\n                        + \"using AutoConsumeSchema because SchemaInfoProvider is not set yet\");\n            } else {\n                SchemaInfo schemaInfo = null;\n                try {\n                    schemaInfo = schemaInfoProvider.getSchemaByVersion(schemaVersion.bytes()).get();\n                    if (schemaInfo == null) {\n                        // schemaless topic\n                        schemaInfo = BytesSchema.of().getSchemaInfo();\n                    }\n                } catch (InterruptedException | ExecutionException e) {\n                    if (e instanceof InterruptedException) {\n                        Thread.currentThread().interrupt();\n                    }\n                    log.error().attr(\"topic\", topicName).log(\"Can't get last schema for topic using AutoConsumeSchema\");\n                    throw new SchemaSerializationException(e.getCause());\n                }\n                // schemaInfo null means that there is no schema attached to the topic.\n                Schema<?> schema = generateSchema(schemaInfo);","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/AutoConsumeSchema.java#L323-L359","documentation":"AutoConsumeSchema needs the broker's SchemaInfoProvider to look up a schema for an unknown schema version. If the provider was never set (schemaInfoProvider == null) and a new schema version is encountered, it throws SchemaSerializationException because it cannot resolve the schema for that version.","triggerScenarios":"fetchSchemaIfNeeded is invoked (from decode, atSchemaVersion, or unwrapInternalSchema) with a schema version absent from schemaMap while the schema was constructed without a SchemaInfoProvider — typically a manually instantiated AutoConsumeSchema rather than one wired by the consumer.","commonSituations":"Building AutoConsumeSchema by hand in tests or tools without calling setSchemaInfoProvider; using the schema outside a real consumer connection so no provider is attached.","solutions":["Attach a SchemaInfoProvider via schema.setSchemaInfoProvider(...) before decoding","Use Schema.AUTO_CONSUME() through the normal consumer builder so the client wires the provider automatically","Catch SchemaSerializationException and fall back to raw byte consumption"],"exampleFix":"// before\nAutoConsumeSchema s = new AutoConsumeSchema();\nGenericRecord r = s.decode(bytes, version); // throws\n// after\nAutoConsumeSchema s = new AutoConsumeSchema();\ns.setSchemaInfoProvider(myProvider);\ns.fetchSchemaIfNeeded(BytesSchemaVersion.of(version));\nGenericRecord r = s.decode(bytes, version);","handlingStrategy":"validation","validationCode":"if (autoSchema.getSchemaInfoProvider() == null) {\n    throw new IllegalStateException(\"Attach a SchemaInfoProvider before decoding with AutoConsumeSchema\");\n}","typeGuard":"boolean hasProvider(AutoConsumeSchema s) {\n    return s != null && s.getSchemaInfoProvider() != null;\n}","tryCatchPattern":"try {\n    schema.fetchSchemaIfNeeded(version);\n} catch (SchemaSerializationException e) {\n    // fall back to raw byte consumption or attach a provider and retry\n}","preventionTips":["Construct AutoConsumeSchema via Schema.AUTO_CONSUME() so the client wires the provider","When instantiating manually, always call setSchemaInfoProvider first","In offline/test contexts, provide a static SchemaInfoProvider backed by known schemas"],"tags":["pulsar","schema","auto-consume","schema-info-provider","serialization"],"backgroundTag":"schema-provider-not-set","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}