apache/iceberg · error · IllegalArgumentException

Unknown task type:

Error message

Unknown task type: 

What it means

ScanTaskParser.TaskType.fromTypeName maps a JSON 'task-type' string to the internal TaskType enum (file-scan-task, data-task, files-table-task, all-manifests-table-task, manifest-entries-task). When the string does not case-insensitively match any known type name, it throws this IllegalArgumentException. It guards against deserializing scan task JSON written by a newer or incompatible Iceberg version.

Source

Thrown at core/src/main/java/org/apache/iceberg/ScanTaskParser.java:58

    TaskType(String value) {
      this.value = value;
    }

    public static TaskType fromTypeName(String value) {
      Preconditions.checkArgument(
          !Strings.isNullOrEmpty(value), "Invalid task type name: null or empty");
      if (FILE_SCAN_TASK.typeName().equalsIgnoreCase(value)) {
        return FILE_SCAN_TASK;
      } else if (DATA_TASK.typeName().equalsIgnoreCase(value)) {
        return DATA_TASK;
      } else if (FILES_TABLE_TASK.typeName().equalsIgnoreCase(value)) {
        return FILES_TABLE_TASK;
      } else if (ALL_MANIFESTS_TABLE_TASK.typeName().equalsIgnoreCase(value)) {
        return ALL_MANIFESTS_TABLE_TASK;
      } else if (MANIFEST_ENTRIES_TABLE_TASK.typeName().equalsIgnoreCase(value)) {
        return MANIFEST_ENTRIES_TABLE_TASK;
      } else {
        throw new IllegalArgumentException("Unknown task type: " + value);
      }
    }

    public String typeName() {
      return value;
    }
  }

  private ScanTaskParser() {}

  public static String toJson(FileScanTask fileScanTask) {
    Preconditions.checkArgument(fileScanTask != null, "Invalid scan task: null");
    return JsonUtil.generate(generator -> toJson(fileScanTask, generator), false);
  }

  public static FileScanTask fromJson(String json, boolean caseSensitive) {
    Preconditions.checkArgument(json != null, "Invalid JSON string for scan task: null");
    return JsonUtil.parse(json, node -> fromJson(node, caseSensitive));

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the 'task-type' value in the JSON against the known names: file-scan-task, data-task, files-table-task, all-manifests-table-task, manifest-entries-task
  2. Upgrade the Iceberg version on the reading side to match or exceed the version that wrote the JSON
  3. Fix typos in the task-type string (matching is case-insensitive, so casing alone is safe)

Example fix

// before
FileScanTask task = ScanTaskParser.fromJson(json, true); // json has "task-type": "position-delete-scan-task"
// after
String type = JsonUtil.getStringOrNull("task-type", node);
if (type != null && !List.of("file-scan-task","data-task","files-table-task","all-manifests-table-task","manifest-entries-task").contains(type.toLowerCase(Locale.ROOT))) {
  throw new IllegalStateException("Unsupported task type in payload: " + type + "; upgrade Iceberg");
}
FileScanTask task = ScanTaskParser.fromJson(json, true);
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> KNOWN = Set.of("file-scan-task","data-task","files-table-task","all-manifests-table-task","manifest-entries-task");
String type = node.has("task-type") ? node.get("task-type").asText() : "file-scan-task";
if (!KNOWN.contains(type.toLowerCase(Locale.ROOT))) throw new IllegalArgumentException("Unsupported task-type: " + type);

Type guard

static boolean isKnownTaskType(String s) {
  return s != null && (s.equalsIgnoreCase("file-scan-task") || s.equalsIgnoreCase("data-task") || s.equalsIgnoreCase("files-table-task") || s.equalsIgnoreCase("all-manifests-table-task") || s.equalsIgnoreCase("manifest-entries-task"));
}

Try / catch

try {
  return ScanTaskParser.fromJson(json, caseSensitive);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Unknown task type")) { log.warn("Skipping task JSON from newer Iceberg: {}", e.getMessage()); return null; }
  throw e;
}

Prevention

When it happens

Trigger: Calling ScanTaskParser.fromJson(String, boolean) on JSON whose 'task-type' field holds a value outside the five known names (typo, unknown type from a newer Iceberg release, or a custom ScanTask serialized by another writer).

Common situations: Rolling upgrades where tasks serialized by a newer Iceberg version (with new task types) are read by an older client; hand-edited or copy-pasted task JSON; metadata/metadata-log tooling passing raw strings into the parser.

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/5df898a4c9012412. Report an issue: GitHub.