apache/beam · error · IllegalArgumentException
PCollection does not use a KvCoder
Error message
PCollection does not use a KvCoder
What it means
When inferring the key coder from an input PCollection, the tuple requires the PCollection's coder to be a KvCoder so it can extract coder.getKeyCoder(). A non-KvCoder coder means the input isn't a properly-coded KV PCollection.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/join/KeyedPCollectionTuple.java:163
/** Returns the {@link CoGbkResultSchema} associated with this {@link KeyedPCollectionTuple}. */
public CoGbkResultSchema getCoGbkResultSchema() {
return schema;
}
@Override
public Pipeline getPipeline() {
return pipeline;
}
private static <K, V> Coder<K> getKeyCoder(PCollection<KV<K, V>> pc) {
// TODO: This should already have run coder inference for output, but may not have been consumed
// as input yet (and won't be fully specified); This is fine
// Assumes that the PCollection uses a KvCoder.
Coder<?> entryCoder = pc.getCoder();
if (!(entryCoder instanceof KvCoder<?, ?>)) {
throw new IllegalArgumentException("PCollection does not use a KvCoder");
}
@SuppressWarnings("unchecked")
KvCoder<K, V> coder = (KvCoder<K, V>) entryCoder;
return coder.getKeyCoder();
}
/////////////////////////////////////////////////////////////////////////////
/** A utility class to help ensure coherence of tag and input PCollection types. */
public static class TaggedKeyedPCollection<K, V> {
final TupleTag<V> tupleTag;
final PCollection<KV<K, V>> pCollection;
public TaggedKeyedPCollection(TupleTag<V> tupleTag, PCollection<KV<K, V>> pCollection) {
this.tupleTag = tupleTag;
this.pCollection = pCollection;
}View on GitHub (pinned to 12126d8942)
Solutions
- Set a KvCoder on the PCollection before adding it to the KeyedPCollectionTuple
- Use KvCoder.of(keyCoder, valueCoder) and pc.setCoder(...) for inputs from custom IO
- Inspect pc.getCoder() type during debugging to confirm it is KvCoder
Example fix
// before tuple.and(tag, pcWithoutKvCoder); // throws // after pc.setCoder(KvCoder.of(StringUtf8Coder.of(), valueCoder)); tuple.and(tag, pc);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(pc.getCoder() instanceof KvCoder)) { throw new IllegalArgumentException("KeyedPCollectionTuple input needs a KvCoder"); } Type guard
if (pc.getCoder() instanceof KvCoder<?, ?> kvCoder) { return kvCoder.getKeyCoder(); } Try / catch
try { return getKeyCoder(pc); } catch (IllegalArgumentException e) { pc.setCoder(KvCoder.of(defaultKeyCoder, defaultValueCoder)); return defaultKeyCoder; } Prevention
- Set KvCoder on inputs before and()
- Use coder inference verified transforms upstream
- Unit-test coder types of custom source outputs
When it happens
Trigger: Adding a PCollection to a KeyedPCollectionTuple whose coder is not a KvCoder, forcing getKeyCoder(pc) inference to fail — same root cause as error 556 but on KeyedPCollectionTuple.and()/getKeyCoder paths.
Common situations: Custom sources producing KVs without a KvCoder; PTransforms that set an explicit non-KvCoder coder on a KV PCollection before a join.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- PCollection does not use a KvCoder
- Invalid encoded string length: {}
- cannot encode a null String
- cannot encode a null Integer
- error when decoding a textual integer
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/5c9758f17a102198.
Report an issue: GitHub.