{"record":{"id":"6542c7286a36d7ed","repo":"apache/flink","slug":"schema-must-be-set-when-using-generic-record","errorCode":null,"errorMessage":"Schema must be set when using Generic Record","messagePattern":"Schema must be set when using Generic Record","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink-formats/flink-avro/src/main/java/org/apache/flink/formats/avro/AvroOutputFormat.java","lineNumber":140,"sourceCode":"\n    @Override\n    public void open(InitializationContext context) throws IOException {\n        super.open(context);\n\n        DatumWriter<E> datumWriter;\n        Schema schema;\n        if (org.apache.avro.specific.SpecificRecordBase.class.isAssignableFrom(avroValueType)) {\n            datumWriter = new SpecificDatumWriter<E>(avroValueType);\n            try {\n                schema =\n                        ((org.apache.avro.specific.SpecificRecordBase) avroValueType.newInstance())\n                                .getSchema();\n            } catch (InstantiationException | IllegalAccessException e) {\n                throw new RuntimeException(e.getMessage());\n            }\n        } else if (org.apache.avro.generic.GenericRecord.class.isAssignableFrom(avroValueType)) {\n            if (userDefinedSchema == null) {\n                throw new IllegalStateException(\"Schema must be set when using Generic Record\");\n            }\n            datumWriter = new GenericDatumWriter<E>(userDefinedSchema);\n            schema = userDefinedSchema;\n        } else {\n            datumWriter = new ReflectDatumWriter<E>(avroValueType);\n            schema = ReflectData.get().getSchema(avroValueType);\n        }\n        dataFileWriter = new DataFileWriter<E>(datumWriter);\n        if (codec != null) {\n            dataFileWriter.setCodec(codec.getCodecFactory());\n        }\n        if (userDefinedSchema == null) {\n            dataFileWriter.create(schema, stream);\n        } else {\n            dataFileWriter.create(userDefinedSchema, stream);\n        }\n    }\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-formats/flink-avro/src/main/java/org/apache/flink/formats/avro/AvroOutputFormat.java#L122-L158","documentation":"Thrown by AvroOutputFormat when the configured record class implements org.apache.avro.generic.GenericRecord but no Avro schema was supplied. Generic records carry no embedded schema (unlike SpecificRecord, whose schema is obtained by instantiating the class), so the output format has nothing to write against and fails fast during open().","triggerScenarios":"new AvroOutputFormat<>(GenericRecord.class (e.g. IndexedRecord/DataFileWriter path), codec) or AvroOutputFormat.writeAvro(...)'s overload that takes no schema, where the value type is GenericRecord but not SpecificRecordBase; the constructor's userDefinedSchema stays null.","commonSituations":"Switching a job from an Avro-generated SpecificRecord class to GenericData.Record or AvroUtils-supported generic records without adding a schema; using the deprecated no-schema factory method; refactoring tuple->pojo->generic avro types.","solutions":["Pass an explicit org.apache.avro.Schema to the AvroOutputFormat constructor (or use the builder/factory overload that accepts a schema string) so userDefinedSchema is non-null.","If you have a generated class, use the Avro-codegen'd SpecificRecord subclass instead of a raw GenericRecord so the schema is auto-derived.","If the schema lives in a file/classpath resource, load and parse it with new Schema.Parser().parse(...) and hand it to the format before open()."],"exampleFix":"// before\nAvroOutputFormat<GenericRecord> out =\n    new AvroOutputFormat<>(new Path(path), GenericRecord.class);\n\n// after\nSchema schema = new Schema.Parser().parse(\n    new InputStreamReader(getClass().getResourceAsStream(\"/event.avsc\")));\nAvroOutputFormat<GenericRecord> out =\n    new AvroOutputFormat<>(new Path(path), GenericRecord.class, schema);","handlingStrategy":"validation","validationCode":"if (GenericRecord.class.isAssignableFrom(recordClass)\n        && !SpecificRecordBase.class.isAssignableFrom(recordClass)\n        && schema == null) {\n    throw new IllegalArgumentException(\"AvroOutputFormat needs an explicit Schema for GenericRecord types: \"\n        + recordClass.getName());\n}","typeGuard":"static boolean needsExplicitSchema(Class<?> c, Schema s) {\n    return GenericRecord.class.isAssignableFrom(c)\n            && !SpecificRecordBase.class.isAssignableFrom(c)\n            && s == null;\n}","tryCatchPattern":null,"preventionTips":["Treat schema as mandatory whenever the record type is GenericRecord; assert it in job setup code.","Prefer generated SpecificRecord classes so the schema is derived automatically.","Unit-test output format open() locally before deploying."],"tags":["avro","flink","batch","schema","configuration"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}