apache/iceberg · error · IllegalArgumentException

unsupported strategy: ${strategy}. Only binpack or sort is s

Error message

unsupported strategy: ${strategy}. Only binpack or sort is supported

What it means

checkAndApplyStrategy validates the strategy option of RewriteDataFilesProcedure. Only 'binpack' (default) and 'sort' are supported; any other value results in this IllegalArgumentException. Note the throw also fires when both a binpack strategy and a sort order were set, since that combination falls into the else branch.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/procedures/RewriteDataFilesProcedure.java:201

                .flatMap(zOrder -> zOrder.refs().stream().map(NamedReference::name))
                .toArray(String[]::new);
        return action.zOrder(columnNames);
      } else if (!sortOrderFields.isEmpty()) {
        return action.sort(buildSortOrder(sortOrderFields, schema));
      } else {
        return action.sort();
      }
    }
    if (strategy.equalsIgnoreCase("binpack")) {
      RewriteDataFiles rewriteDataFiles = action.binPack();
      if (sortOrderString != null) {
        // calling below method to throw the error as user has set both binpack strategy and sort
        // order
        return rewriteDataFiles.sort(buildSortOrder(sortOrderFields, schema));
      }
      return rewriteDataFiles;
    } else {
      throw new IllegalArgumentException(
          "unsupported strategy: " + strategy + ". Only binpack or sort is supported");
    }
  }

  private SortOrder buildSortOrder(
      List<ExtendedParser.RawOrderField> rawOrderFields, Schema schema) {
    SortOrder.Builder builder = SortOrder.builderFor(schema);
    rawOrderFields.forEach(
        rawField -> builder.sortBy(rawField.term(), rawField.direction(), rawField.nullOrder()));
    return builder.build();
  }

  private InternalRow[] toOutputRows(RewriteDataFiles.Result result) {
    int rewrittenDataFilesCount = result.rewrittenDataFilesCount();
    long rewrittenBytesCount = result.rewrittenBytesCount();
    int addedDataFilesCount = result.addedDataFilesCount();
    int failedDataFilesCount = result.failedDataFilesCount();
    int removedDeleteFilesCount = result.removedDeleteFilesCount();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Set strategy => 'sort' when using sort_order (including zorder(...) terms).
  2. Set strategy => 'binpack' and omit sort_order for pure compaction.
  3. Check spelling/typos of the strategy option value; it must be exactly 'binpack' or 'sort'.

Example fix

// before
CALL iceberg.system.rewrite_data_files(table => 'db.t', strategy => 'binpack', sort_order => 'id');
// after
CALL iceberg.system.rewrite_data_files(table => 'db.t', strategy => 'sort', sort_order => 'id');
Defensive patterns

Strategy: validation

Validate before calling

String strategy = options.getOrDefault("strategy", "binpack");
if (!strategy.equals("binpack") && !strategy.equals("sort")) {
  throw new IllegalArgumentException("strategy must be 'binpack' or 'sort'");
}
if (strategy.equals("binpack") && options.containsKey("sort_order")) {
  throw new IllegalArgumentException("sort_order requires strategy 'sort'");
}

Prevention

When it happens

Trigger: CALL rewrite_data_files with strategy => 'auto', 'zorder' (as a strategy name), or any misspelled value; or setting strategy => 'binpack' together with a sort_order option.

Common situations: Typos in strategy ('sorted', 'sorts'), assuming 'zorder' is a strategy (it is expressed via sort_order), and setting sort_order while leaving strategy at binpack.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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