Skip to content

REST create_table omits partition spec-id; Java-based servers (Polaris) reject it #3469

Open

Description

@luke-kucing

Apache Iceberg Rust version

0.10.1 (also present on main at 3bb8167)

Describe the bug

RestCatalog::create_table serializes the partition spec without spec-id when the UnboundPartitionSpec has none set. Since #2610, unset ids are omitted rather than sent as null.

Servers that parse the request with Iceberg Java's PartitionSpecParser require spec-id. For example, Apache Polaris 1.3.0 rejects the request with a bare HTTP 400 Bad Request (WebApplicationException) and logs nothing that points to the cause. Building the spec with .with_spec_id(0) makes the same request succeed.

#2702 notes the same parser behaviour for TableUpdate::AddSpec on the commit path. The create-table path hits it too.

To Reproduce

  1. Start Polaris 1.3.0 (in-memory persistence, bootstrap credentials) with an internal catalog.
  2. Create a table through RestCatalog with a partition spec built by UnboundPartitionSpec::builder().add_partition_field(...), without with_spec_id.
  3. Polaris answers 400.

The same request body replayed with curl:

  • "partition-spec": {"fields": [{"source-id": 27, "name": "receive_day", "transform": "day"}]} returns 400.
  • "partition-spec": {"spec-id": 0, "fields": [...]} returns 200.
  • Adding a field-id without spec-id still returns 400.

Expected behavior

A table created through the REST catalog with an unbound partition spec is accepted by Java-based REST servers. One option is to send spec-id: 0 in CreateTableRequest when it is unset, since a new table's first spec is always 0.

Willingness to contribute

Happy to test a fix against Polaris.


AI disclosure: drafted with an AI coding assistant; reproduced and verified by me.

Activity

  1. ahlag commented on Oct 17, 2026

    @ahlag

    I'd like to take this. Draft fix in #3484: create_table now sends spec-id: 0 when the partition spec has none, applied where the request is built so TableUpdate::AddSpec serialization is unchanged, and test_create_table now checks the request body. I'll mark it ready for review once CI passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions