apache/iceberg · error · UnsupportedOperationException

Cannot unset reserved property

Error message

Cannot unset reserved property: '%s'

What it means

SparkView defines reserved properties that are managed by Iceberg/Spark and cannot be removed by users. verifyNonReservedPropertyIsUnset() rejects a RemoveProperty change whose key is in SparkView.RESERVED_PROPERTIES, throwing UnsupportedOperationException with 'Cannot unset reserved property'. Setting a reserved key is rejected by the sibling check with a similar message.

Solutions

  1. Remove the reserved key from the UNSET/RemoveProperty list and only unset user-defined properties
  2. Read the reserved property instead of trying to change it if you need its value — it is derived metadata
  3. Filter the property list programmatically before calling alterView

Example fix

// before
viewCatalog.alterView(ident, ViewChange.removeProperty("provider"));
// after
if (!SparkView.RESERVED_PROPERTIES.contains("owner")) {
  viewCatalog.alterView(ident, ViewChange.removeProperty("owner"));
}
Defensive patterns

Strategy: validation

Validate before calling

// Check against reserved properties before altering
java.util.Set<String> reserved = org.apache.iceberg.spark.SparkView.RESERVED_PROPERTIES;
java.util.List<String> keys = changes.stream()
    .filter(c -> c instanceof ViewChange.RemoveProperty)
    .map(c -> ((ViewChange.RemoveProperty) c).property())
    .toList();
if (keys.stream().anyMatch(reserved::contains)) {
  throw new IllegalArgumentException("Reserved properties cannot be unset: " + keys);
}

Type guard

boolean isReserved(String property) {
  return org.apache.iceberg.spark.SparkView.RESERVED_PROPERTIES.contains(property);
}

Try / catch

try {
  catalog.alterView(ident, ViewChange.removeProperty(key));
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Cannot unset reserved property")) {
    logger.warn("Skipping reserved property {}", key);
  }
}

Prevention

When it happens

Trigger: Calling SparkCatalog.alterView (or ALTER VIEW ... UNSET TBLPROPERTIES) with a property name contained in SparkView.RESERVED_PROPERTIES (e.g. 'provider', 'format', 'location' style reserved keys).

Common situations: Copy-pasting UNSET TBLPROPERTIES statements meant for tables; scripts that blindly unset all properties including internal ones; attempting to clear metadata Iceberg computes itself.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:730

            updateViewProperties.remove(remove.property());
          }
        }

        updateViewProperties.commit();

        return new SparkView(catalogName, view);
      } catch (org.apache.iceberg.exceptions.NoSuchViewException e) {
        throw new NoSuchViewException(ident);
      }
    }

    throw new UnsupportedOperationException(
        "Altering a view is not supported by catalog: " + catalogName);
  }

  private static void verifyNonReservedProperty(String property, String errorMsg) {
    if (SparkView.RESERVED_PROPERTIES.contains(property)) {
      throw new UnsupportedOperationException(String.format(errorMsg, property));
    }
  }

  private static void verifyNonReservedPropertyIsUnset(String property) {
    verifyNonReservedProperty(property, "Cannot unset reserved property: '%s'");
  }

  private static void verifyNonReservedPropertyIsSet(String property) {
    verifyNonReservedProperty(property, "Cannot set reserved property: '%s'");
  }

  @Override
  public boolean dropView(Identifier ident) {
    if (null != asViewCatalog) {
      return asViewCatalog.dropView(buildIdentifier(ident));
    }

    return false;

View on GitHub (pinned to 86d9c8fc54)