apache/iceberg · error · UnsupportedOperationException

Unrecognized update requirement. Cannot convert to json: %s

Error message

Unrecognized update requirement. Cannot convert to json: %s

What it means

Thrown by UpdateRequirementParser.fromJson when the 'type' field in the JSON is not one of the recognized requirement types. This happens when a REST catalog server (or newer client) sends an update-requirement of a type this Iceberg version does not know. The parser throws UnsupportedOperationException instead of silently dropping the assertion, because ignoring a requirement could wrongly allow an unsafe commit.

Source

Thrown at core/src/main/java/org/apache/iceberg/UpdateRequirementParser.java:182

        return readAssertTableDoesNotExist(jsonNode);
      case ASSERT_TABLE_UUID:
        return readAssertTableUUID(jsonNode);
      case ASSERT_VIEW_UUID:
        return readAssertViewUUID(jsonNode);
      case ASSERT_REF_SNAPSHOT_ID:
        return readAssertRefSnapshotId(jsonNode);
      case ASSERT_LAST_ASSIGNED_FIELD_ID:
        return readAssertLastAssignedFieldId(jsonNode);
      case ASSERT_LAST_ASSIGNED_PARTITION_ID:
        return readAssertLastAssignedPartitionId(jsonNode);
      case ASSERT_CURRENT_SCHEMA_ID:
        return readAssertCurrentSchemaId(jsonNode);
      case ASSERT_DEFAULT_SPEC_ID:
        return readAssertDefaultSpecId(jsonNode);
      case ASSERT_DEFAULT_SORT_ORDER_ID:
        return readAssertDefaultSortOrderId(jsonNode);
      default:
        throw new UnsupportedOperationException(
            String.format("Unrecognized update requirement. Cannot convert to json: %s", type));
    }
  }

  private static void writeAssertTableUUID(
      UpdateRequirement.AssertTableUUID requirement, JsonGenerator gen) throws IOException {
    gen.writeStringField(UUID, requirement.uuid());
  }

  private static void writeAssertViewUUID(
      UpdateRequirement.AssertViewUUID requirement, JsonGenerator gen) throws IOException {
    gen.writeStringField(UUID, requirement.uuid());
  }

  private static void writeAssertRefSnapshotId(
      UpdateRequirement.AssertRefSnapshotID requirement, JsonGenerator gen) throws IOException {
    gen.writeStringField(NAME, requirement.refName());
    if (requirement.snapshotId() != null) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the Iceberg client library to a version whose parser knows the requirement type sent by the server (keep client and catalog server spec versions aligned).
  2. Check the exact 'type' string in the JSON payload for typos or unexpected values (log the payload before parsing).
  3. If the server emits a vendor extension, either disable that server feature or filter/reject such requirements before parse — never ignore them silently.
  4. Ensure no older shaded iceberg-core copy intercepts parsing (single consistent Iceberg version on the classpath).

Example fix

// before: iceberg-core 1.4 client parsing 1.6 server requirements
List<UpdateRequirement> reqs = UpdateRequirementParser.fromJson(node); // throws
// after: upgrade client
// implementation 'org.apache.iceberg:iceberg-core:1.6.1'
// or defensively:
String type = node.get("type").textValue();
if (!KNOWN_TYPES.contains(type)) {
  throw new IllegalStateException("Unsupported requirement type from server: " + type);
}
Defensive patterns

Strategy: try-catch

Validate before calling

String type = jsonNode.get("type") != null ? jsonNode.get("type").textValue() : null;
if (type == null || !KNOWN_REQUIREMENT_TYPES.contains(type)) {
  throw new IllegalStateException("Unknown requirement type from server: " + type);
}

Type guard

boolean isKnownRequirementType(String type) {
  return type != null && Set.of("assert-table-uuid", "assert-last-assigned-field-id",
      "assert-current-schema-id", "assert-last-assigned-partition-id",
      "assert-default-spec-id", "assert-default-sort-order-id",
      "assert-ref-snapshot-id").contains(type);
}

Try / catch

try {
  List<UpdateRequirement> reqs = UpdateRequirementParser.fromJson(node);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unrecognized update requirement")) {
    throw new IllegalStateException("Server sent a requirement type this client does not support; upgrade iceberg-core", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Parsing a JSON requirements array (e.g. from a REST catalog commit response or stored file) whose 'type' value is absent from {assert-table-uuid, assert-last-assigned-field-id, assert-current-schema-id, assert-last-assigned-partition-id, assert-default-spec-id, assert-default-sort-order-id, assert-ref-snapshot-id} — typically a requirement added in a newer Iceberg spec version.

Common situations: Client on older Iceberg reading requirements produced by a newer REST catalog/server; typo'd or hand-edited requirement JSON; a server implementing a vendor-specific requirement extension not in the client's spec version.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/b07d7e27ff1f1110. Report an issue: GitHub.