apache/beam · error · IllegalArgumentException

Unknown type {}

Error message

Unknown type {}

What it means

MutationKeyEncoder.encodeKey() maps each Spanner Key value's Type code to an ordered-code writer. When a key column has a Type code that the encoder does not handle (e.g. STRUCT or other non-scalar types used as key), the default branch throws IllegalArgumentException('Unknown type ...'). Spanner primary keys only support scalar types, so this indicates a non-scalar or newly added type reached the encoder.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationKeyEncoder.java:144

            writeString(orderedCode, part, val.getString());
            break;
          case BYTES:
            writeBytes(orderedCode, part, val.getBytes());
            break;
          case TIMESTAMP:
            writeTimestamp(orderedCode, part, val.getTimestamp());
            break;
          case DATE:
            writeNumber(orderedCode, part, encodeDate(val.getDate()));
            break;
          case NUMERIC:
            writeString(orderedCode, part, val.getNumeric().toString());
            break;
          case JSON:
            writeString(orderedCode, part, val.getJson());
            break;
          default:
            throw new IllegalArgumentException("Unknown type " + val.getType());
        }
      }
    }
  }

  private void encodeKey(OrderedCode orderedCode, String tableName, Key key) {
    List<SpannerSchema.KeyPart> parts = schema.getKeyParts(tableName);
    Iterator<Object> it = key.getParts().iterator();
    for (SpannerSchema.KeyPart part : parts) {
      Object value = it.next();
      if (value == null) {
        if (part.isDesc()) {
          orderedCode.writeInfinityDecreasing();
        } else {
          orderedCode.writeInfinity();
        }
      } else {
        if (value instanceof Boolean) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the table's primary key uses supported scalar types (STRING, INT64, FLOAT64, BOOL, TIMESTAMP, DATE, NUMERIC, JSON, BYTES).
  2. Upgrade the Beam google-cloud-platform SDK so the encoder recognizes newer Spanner Type codes.
  3. Re-map your mutation to encode the offending column into a supported scalar before writing.

Example fix

// before: key column is STRUCT/ARRAY — not encodable
// after: use a scalar STRING key column, or hash the composite value into a STRING key
Defensive patterns

Strategy: validation

Validate before calling

for (Value v : key.values()) {
  if (!Set.of("STRING","INT64","FLOAT64","BOOL","TIMESTAMP","DATE","NUMERIC","JSON","BYTES").contains(v.getType().getCode().name()))
    throw new IllegalArgumentException("unsupported key type: " + v.getType());
}

Type guard

boolean isEncodableKeyType(Type t) { return t.getCode() != Type.Code.STRUCT && t.getCode() != Type.Code.ARRAY; }

Try / catch

try { writeResult = pipeline.apply(SpannerIO.write()...) } catch (IllegalArgumentException e) { /* fix key schema */ }

Prevention

When it happens

Trigger: Writing to a Cloud Spanner table whose primary key column is of a type the encoder lacks a case for (e.g. STRUCT, or a newer Spanner type when running an older Beam version); the type comes from the actual key Value in the mutation.

Common situations: Spanner schema has an unusual key column type; Beam/google-cloud-spanner library version mismatch introduces a Type code the Beam encoder doesn't know; reading from one Spanner DB and writing to another with a different key schema.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/25eccc89f6728e79. Report an issue: GitHub.