{"record":{"id":"197b7f9aec07aac5","repo":"apache/beam","slug":"unknowncoderwrapper-was-used-to-perform-an-actual-decoding","errorCode":null,"errorMessage":"`UnknownCoderWrapper` was used to perform an actual decoding in the Java SDK. Potentially a Java transform is being followed by a cross-language transform that uses a coder that is not available in the Java SDK. Please make sure that Python transforms at the multi-language boundary use Beam portable coders.","messagePattern":"`UnknownCoderWrapper` was used to perform an actual decoding in the Java SDK\\. Potentially a Java transform is being followed by a cross-language transform that uses a coder that is not available in the Java SDK\\. Please make sure that Python transforms at the multi-language boundary use Beam portable coders\\.","errorType":"exception","errorClass":"CoderException","httpStatus":null,"severity":"critical","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/UnknownCoderWrapper.java","lineNumber":55,"sourceCode":"  }\n\n  public static UnknownCoderWrapper of(String urn, byte[] payload) {\n    return new UnknownCoderWrapper(urn, payload);\n  }\n\n  @Override\n  public void encode(Object value, OutputStream outStream) throws CoderException, IOException {\n    throw new CoderException(\n        \"`UnknownCoderWrapper` was used to perform an actual encoding in the Java SDK. \"\n            + \"Potentially a `PCollection` that was generated by a cross-language transform, \"\n            + \"that uses a coder that is not available in the Java SDK, is being consumed by a Java\"\n            + \" transform. Please make sure that cross-language transforms at the language \"\n            + \"boundary use Beam portable coders.\");\n  }\n\n  @Override\n  public Object decode(InputStream inStream) throws CoderException, IOException {\n    throw new CoderException(\n        \"`UnknownCoderWrapper` was used to perform an actual decoding in the Java SDK. \"\n            + \"Potentially a Java transform is being followed by a cross-language transform that \"\n            + \"uses a coder that is not available in the Java SDK. Please make sure that Python \"\n            + \"transforms at the multi-language boundary use Beam portable coders.\");\n  }\n\n  public String getUrn() {\n    return urn;\n  }\n\n  public byte[] getPayload() {\n    return payload;\n  }\n}\n","sourceCodeStart":37,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/UnknownCoderWrapper.java#L37-L70","documentation":"The decode() counterpart of UnknownCoderWrapper: when the Java SDK must deserialize elements from a PCollection produced upstream by a cross-language transform whose coder it cannot resolve, decode() intentionally throws this CoderException. It signals the multi-language boundary is not using Beam portable coders.","triggerScenarios":"A Java transform (or the runner materializing data) reads a PCollection whose coder is an UnknownCoderWrapper — i.e., an upstream Java transform is followed by a cross-language transform using a coder not available in the Java SDK — and UnknownCoderWrapper.decode(InputStream) is invoked.","commonSituations":"Java pipeline step feeding a Python transform whose input coder was overridden with a Python-specific custom coder; expansion service registers coders under URNs the Java SDK doesn't know; Beam version skew between the two SDKs.","solutions":["Ensure the coder used at the multi-language boundary is a Beam portable coder resolvable in both the Java and Python SDKs.","If you own the Python transform, change its input/output coder registration to a portable (URN-based) coder.","Register a mapping for the unknown coder URN in the Java coder registry so a concrete Java coder is resolved instead of the wrapper.","Align Beam SDK versions across Java, Python, and the expansion service so coder URNs are mutually known."],"exampleFix":"// before: piping a Java PCollection into a Python transform with a custom Python coder\nPCollection<MyType> out = pc.apply(\"PyStep\", PyTransform.of(args));\n// after: explicitly set a portable coder (e.g. beam row / protobuf-based) on the boundary\nPCollection<MyType> out = pc\n    .setCoder(MyPortableRowCoder.of())\n    .apply(\"PyStep\", PyTransform.of(args));","handlingStrategy":"validation","validationCode":"// Before piping a Java PCollection into a cross-language transform, ensure the coder is portable\nCoder<?> c = input.getCoder();\nif (c instanceof UnknownCoderWrapper) {\n  throw new IllegalStateException(\n      \"Input to cross-language transform uses an unknown coder; set a portable coder first.\");\n}","typeGuard":"boolean isUnknownCoder(Coder<?> coder) {\n  return coder instanceof org.apache.beam.sdk.util.construction.UnknownCoderWrapper;\n}","tryCatchPattern":"try {\n  input.apply(\"CrossLanguageStep\", pyTransform);\n} catch (CoderException e) {\n  if (String.valueOf(e.getMessage()).contains(\"UnknownCoderWrapper\")) {\n    // set an explicit portable coder on the boundary PCollection and resubmit\n  }\n  throw e;\n}","preventionTips":["Explicitly call PCollection.setCoder(...) with a portable coder at every multi-language boundary.","Verify the Python transform's coder is registered under a URN the Java SDK knows.","Align Beam SDK versions between Java, Python, and the expansion service.","Run a smoke-test pipeline through the expansion service before production."],"tags":["cross-language","coder","deserialization","java","portability"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}