apache/beam · error · NullPointerException

Null key

Error message

Null key

What it means

BeamRowToBigtableMutation.apply converts a Beam Row into a Bigtable row keyed by the value of the schema field named KEY. Bigtable rows require a non-null row key; if row.getString(KEY) returns null the transform throws a NullPointerException("Null key") because a mutation without a key is meaningless.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BeamRowToBigtableMutation.java:97

    private final Map<String, String> columnFamilyMapping;
    private final CellValueParser cellValueParser = new CellValueParser();

    public ToBigtableRowFn(Map<String, String> columnFamilyMapping) {
      this.columnFamilyMapping = columnFamilyMapping;
    }

    @Override
    public KV<ByteString, Iterable<Mutation>> apply(Row row) {
      List<Mutation> mutations =
          columnFamilyMapping.entrySet().stream()
              .map(columnFamily -> mutation(columnFamily.getValue(), columnFamily.getKey(), row))
              .collect(toList());
      String key = row.getString(KEY);
      if (key != null) {
        return KV.of(ByteString.copyFromUtf8(key), mutations);
      } else {
        throw new NullPointerException("Null key");
      }
    }

    private Mutation mutation(String family, String column, Row row) {
      return Mutation.newBuilder()
          .setSetCell(
              Mutation.SetCell.newBuilder()
                  .setValue(convertValueToByteString(row, column))
                  .setColumnQualifier(ByteString.copyFromUtf8(column))
                  .setFamilyName(family)
                  .build())
          .build();
    }

    private ByteString convertValueToByteString(Row row, String column) {
      Schema.Field field = row.getSchema().getField(column);
      Object value = row.getValue(column);
      if (value == null) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Filter out rows with null keys before applying the transform: rows.where key is not null.
  2. Populate the KEY field upstream (derive it from another column or a default).
  3. If null keys are expected, handle them in a separate error/output PCollection instead of the mutation path.

Example fix

// before
rows.apply(BeamRowToBigtableMutation.of(projectId, instanceId, tableId));
// after
rows.apply(Filter.by(r -> r.getString("KEY") != null))
    .apply(BeamRowToBigtableMutation.of(projectId, instanceId, tableId));
Defensive patterns

Strategy: validation

Validate before calling

PCollection<Row> valid = rows.apply(Filter.by(r -> r.getString("KEY") != null));

Type guard

boolean hasKey(Row r) { return r.getString("KEY") != null; }

Try / catch

try { kv.apply(mutationTransform); } catch (NullPointerException e) { log.error("Row missing KEY: {}", e.getMessage()); }

Prevention

When it happens

Trigger: A Row whose schema contains a KEY field but whose value for that field is null is passed to apply().

Common situations: Source data missing the key column; a join or parse step producing null keys; schema declares KEY but upstream records lack it.

Related errors


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