apache/iceberg · error · UnsupportedOperationException

Cannot read without at least one projected column

Error message

Cannot read without at least one projected column

What it means

The VectorizedCombinedScanIterator constructor requires the projected schema to contain at least one column; an empty columns() list throws this UnsupportedOperationException. Vectorized batch reading is meaningless with zero projected columns, so the reader rejects it early.

Source

Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowReader.java:246

        FileIO io,
        EncryptionManager encryptionManager,
        boolean caseSensitive,
        int batchSize,
        boolean reuseContainers) {
      List<FileScanTask> fileTasks =
          StreamSupport.stream(tasks.spliterator(), false)
              .map(CombinedScanTask::files)
              .flatMap(Collection::stream)
              .collect(Collectors.toList());
      this.fileItr = fileTasks.iterator();

      if (fileTasks.stream().anyMatch(TableScanUtil::hasDeletes)) {
        throw new UnsupportedOperationException(
            "Cannot read files that require applying delete files");
      }

      if (expectedSchema.columns().isEmpty()) {
        throw new UnsupportedOperationException(
            "Cannot read without at least one projected column");
      }

      Set<TypeID> unsupportedTypes =
          Sets.difference(
              expectedSchema.columns().stream()
                  .map(c -> c.type().typeId())
                  .collect(Collectors.toSet()),
              SUPPORTED_TYPES);
      if (!unsupportedTypes.isEmpty()) {
        throw new UnsupportedOperationException(
            "Cannot read unsupported column types: " + unsupportedTypes);
      }

      Map<String, ByteBuffer> keyMetadata = Maps.newHashMap();
      fileTasks.stream()
          .map(FileScanTask::file)
          .forEach(file -> keyMetadata.put(file.location(), file.keyMetadata()));

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Project at least one column in the scan schema before reading.
  2. Use metadata/table APIs (row counts, snapshot summaries) instead of a zero-column data scan for count-only workloads.
  3. Fall back to the non-vectorized reader path that tolerates empty projections.
Defensive patterns

Strategy: validation

Validate before calling

Preconditions.checkArgument(!expectedSchema.columns().isEmpty(), "At least one column must be projected");

Type guard

static boolean hasProjection(Schema s) { return !s.columns().isEmpty(); }

Try / catch

try { return new VectorizedCombinedScanIterator(...); } catch (UnsupportedOperationException e) { return emptyOrMetadataResult(...); }

Prevention

When it happens

Trigger: Constructing a VectorizedCombinedScanIterator with an expectedSchema whose columns() list is empty (e.g. scan selecting no columns, or an all-filtered projection).

Common situations: Count-only scans or metadata-style queries accidentally routed through the vectorized Arrow reader; programmatic scans built with an empty projection.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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