{"record":{"id":"de2eb0930d487391","repo":"apache/flink","slug":"unable-to-clone-instance-of-s","errorCode":null,"errorMessage":"Unable to clone instance of %s.","messagePattern":"Unable to clone instance of (.+?)\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/util/InstantiationUtil.java","lineNumber":589,"sourceCode":"            return null;\n        } else {\n            final byte[] serializedObject = serializeObject(obj);\n            return deserializeObject(serializedObject, classLoader);\n        }\n    }\n\n    /**\n     * Unchecked equivalent of {@link #clone(Serializable)}.\n     *\n     * @param obj Object to clone\n     * @param <T> Type of the object to clone\n     * @return The cloned object\n     */\n    public static <T extends Serializable> T cloneUnchecked(T obj) {\n        try {\n            return clone(obj, obj.getClass().getClassLoader());\n        } catch (IOException | ClassNotFoundException e) {\n            throw new RuntimeException(\n                    String.format(\"Unable to clone instance of %s.\", obj.getClass().getName()), e);\n        }\n    }\n\n    /**\n     * Clones the given writable using the {@link IOReadableWritable serialization}.\n     *\n     * @param original Object to clone\n     * @param <T> Type of the object to clone\n     * @return Cloned object\n     * @throws IOException Thrown is the serialization fails.\n     */\n    public static <T extends IOReadableWritable> T createCopyWritable(T original)\n            throws IOException {\n        if (original == null) {\n            return null;\n        }\n","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/InstantiationUtil.java#L571-L607","documentation":"InstantiationUtil.cloneUnchecked clones a Serializable object by serializing it to a byte array and deserializing it with its classloader. If either the serialization or deserialization step fails (IOException), or the object's class cannot be found during deserialization (ClassNotFoundException), this RuntimeException is thrown, naming the class that failed to clone. It is the unchecked equivalent of clone(Serializable) and is heavily used by the runtime to copy function and configuration objects.","triggerScenarios":"Calling InstantiationUtil.cloneUnchecked(obj) (directly or indirectly, e.g. when the runtime clones a user function) where obj or an object reachable from it is not truly serializable, its class is not visible to obj.getClass().getClassLoader(), a transient/NoSerialize path throws in writeObject/readObject, or a custom serialVersionUID mismatch breaks deserialization.","commonSituations":"A user function holds a non-serializable field (e.g. a raw Connection, Thread, or logger-like object) that only fails when the runtime deep-clones it; classes loaded in a child-first classloader that cannot be resolved during deserialization; nested objects whose classes were shaded or relocated between versions.","solutions":["Inspect the cause chain: the wrapped IOException/ClassNotFoundException names what actually broke (a specific field's class is the usual culprit).","Make every field of the target class Serializable or mark non-serializable fields transient and reinitialize them in readObject/writeReplace.","Ensure the object's class and all nested classes are visible to the classloader passed to clone (obj.getClass().getClassLoader()).","Fix serialVersionUID mismatches between the class version that wrote and read the bytes.","As a workaround for avro-like cases, use a copy constructor or a dedicated clone routine instead of serialization-based cloning."],"exampleFix":"// before\npublic class MyFunction extends RichMapFunction<String,String> {\n    private Connection db; // not serializable -> cloneUnchecked fails\n}\n\n// after\npublic class MyFunction extends RichMapFunction<String,String> {\n    private transient Connection db;\n\n    @Override\n    public void open(Configuration parameters) {\n        db = DriverManager.getConnection(url); // reinitialize after cloning\n    }\n}","handlingStrategy":"validation","validationCode":"// Verify serializability before the runtime clones the object\ntry (ByteArrayOutputStream bos = new ByteArrayOutputStream();\n     ObjectOutputStream oos = new ObjectOutputStream(bos)) {\n    oos.writeObject(obj);\n    oos.flush();\n} catch (IOException e) {\n    throw new IllegalStateException(\"obj is not safely serializable: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"// Prefer the checked API and decide policy explicitly\ntry {\n    T copy = InstantiationUtil.clone(obj, cl);\n} catch (IOException | ClassNotFoundException e) {\n    // log class name, fall back to manual copy constructor\n}","preventionTips":["Keep all fields of distributed objects Serializable or transient","Unit-test cloneUnchecked on every custom function class in CI","Never let non-serializable resources (connections, threads) be non-transient fields"],"tags":["serialization","cloning","classloader","runtime"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}