{"record":{"id":"33a0e3fb97116ef3","repo":"apache/flink","slug":"cannot-instantiate-class","errorCode":null,"errorMessage":"Cannot instantiate class.","messagePattern":"Cannot instantiate class\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoSerializer.java","lineNumber":225,"sourceCode":"\n        if (!stateful) {\n            // as a small memory optimization, we can share the same object between instances\n            duplicateSerializers = serializers;\n        }\n        return (TypeSerializer<Object>[]) duplicateSerializers;\n    }\n\n    @Override\n    public T createInstance() {\n        if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()) || isRecord()) {\n            return null;\n        }\n        try {\n            T t = instantiateRaw();\n            initializeFields(t);\n            return t;\n        } catch (Exception e) {\n            throw new RuntimeException(\"Cannot instantiate class.\", e);\n        }\n    }\n\n    private T instantiateRaw() {\n        try {\n            if (constructor == null) {\n                constructor = clazz.getDeclaredConstructor();\n                constructor.setAccessible(true);\n            }\n            return constructor.newInstance();\n        } catch (Exception e) {\n            throw new RuntimeException(\"Cannot instantiate class.\", e);\n        }\n    }\n\n    protected void initializeFields(T t) {\n        for (int i = 0; i < numFields; i++) {\n            if (fields[i] != null) {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoSerializer.java#L207-L243","documentation":"PojoSerializer.createInstance() attempts to build a fresh POJO via reflection (no-arg constructor) and then populate each field with a default instance from its field serializer. This RuntimeException is the outer catch that wraps ANY failure during that two-step process — either raw instantiation failed or field initialization failed. The wrapped cause (getCause()) holds the specific reason (NoSuchMethodException, InvocationTargetException, IllegalAccessException, etc.).","triggerScenarios":"The Flink runtime calls TypeSerializer.createInstance() during keyed-state restoration, spill/reload of POJO data, or when the sort/hash infrastructure needs a scratch instance. The exception fires when the POJO class cannot be reflectively constructed or when a field serializer cannot produce a default value for one of the POJO's fields.","commonSituations":"POJO class has only parameterized constructors and no no-arg constructor; POJO class was relocated or shaded so the loaded class differs from the one the serializer snapshot expects; a nested POJO field type itself lacks a no-arg constructor; the POJO class is not on the TaskManager classpath after a JAR change; the constructor exists but throws internally (e.g., requires a dependency injected at construction time).","solutions":["Inspect the wrapped cause via exception.getCause() — it distinguishes 'no no-arg constructor' from 'constructor threw' from 'field init failed'.","Add a public no-arg constructor to the POJO class (or at minimum an accessible private one — setAccessible is called).","If the POJO genuinely cannot have a no-arg constructor, register a custom TypeSerializer or TypeSerializerSnapshot, or annotate the type so Flink falls back to Kryo/Avro serialization.","Ensure the exact same JAR (including POJO class) is deployed on all TaskManagers and the JobManager.","If the class was refactored/renamed between job versions, implement a TypeSerializerSnapshot migration or reset state from a clean savepoint."],"exampleFix":"// before — POJO with no no-arg constructor\npublic class MyEvent {\n    private String id;\n    public MyEvent(String id) { this.id = id; }\n}\n\n// after — add a no-arg constructor for the serializer\npublic class MyEvent {\n    private String id;\n    public MyEvent() { this.id = \"\"; }  // serializer calls this\n    public MyEvent(String id) { this.id = id; }\n}","handlingStrategy":"validation","validationCode":"// Before using a POJO type, verify it has an accessible no-arg constructor\nimport java.lang.reflect.Constructor;\n\npublic static boolean hasNoArgConstructor(Class<?> clazz) {\n    try {\n        Constructor<?> c = clazz.getDeclaredConstructor();\n        c.setAccessible(true);\n        return true;\n    } catch (NoSuchMethodException | SecurityException e) {\n        return false;\n    }\n}\n\n// Usage in a test or pipeline setup\nif (!hasNoArgConstructor(MyPojo.class)) {\n    throw new IllegalStateException(\n        \"POJO \" + MyPojo.class.getName() + \" needs a no-arg constructor for PojoSerializer\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    T instance = pojoSerializer.createInstance();\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    log.error(\"PojoSerializer.createInstance failed for {}: {}\",\n        pojoSerializer.getClass().getName(), cause != null ? cause : e);\n    // cause is typically NoSuchMethodException, InvocationTargetException,\n    // or IllegalAccessException — handle accordingly\n    throw e;\n}","preventionTips":["Add a public no-arg constructor to every POJO used as a Flink type.","Write a unit test that asserts TypeInformation.of(MyPojo.class).createSerializer(config).createInstance() succeeds for every domain type.","Avoid constructors with side effects or external dependencies.","Run PojoSerializer tests after any class relocation or shading build step."],"tags":["pojo","serialization","reflection","type-system","state-restore"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}