Skip to content

Fix concurrent table commits failing with a fatal 400 instead of a retryable 409#5138

Open
ayushtkn wants to merge 1 commit into
apache:mainfrom
ayushtkn:rety
Open

Fix concurrent table commits failing with a fatal 400 instead of a retryable 409#5138
ayushtkn wants to merge 1 commit into
apache:mainfrom
ayushtkn:rety

Conversation

@ayushtkn

Copy link
Copy Markdown
Member

Polaris' CatalogHandlerUtils replicates Iceberg's CatalogHandlers (as of 1.8.0) and never picked up the RetryableValidationException handling CatalogHandlers.commit() added later. Under concurrency (e.g. writes to different branches of a table, or staged/WAP snapshots), TableMetadata.Builder.addSnapshot throws RetryableValidationException — a ValidationException subclass — which Polaris leaks as a fatal HTTP 400 instead of the retryable 409 the Iceberg client would retry, permanently failing a commit that should succeed on rebase. This mirrors CatalogHandlers.commit(), wrapping the update-apply step to rethrow a CommitFailedException, in both the single-table commit and multi-table commitTransaction paths

Checklist

  • 🛡️ Don't disclose security issues! (contact security@apache.org)
  • 🔗 Clearly explained why the changes are needed, or linked related issues: Fixes #
  • 🧪 Added/updated tests with good coverage, or manually tested (and explained how)
  • 💡 Added comments for complex logic
  • 🧾 Updated CHANGELOG.md (if needed)
  • 📚 Updated documentation in site/content/in-dev/unreleased (if needed)

Copilot AI review requested due to automatic review settings July 24, 2026 08:06
@github-project-automation github-project-automation Bot moved this to PRs In Progress in Basic Kanban Board Jul 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Polaris’ Iceberg REST commit handling so concurrency-triggered RetryableValidationException is surfaced as a retryable conflict (HTTP 409 via CommitFailedException) rather than a fatal validation error (HTTP 400 via ValidationException), aligning behavior with Iceberg’s catalog handler semantics.

Changes:

  • Catch RetryableValidationException while applying MetadataUpdates and rethrow as CommitFailedException in the single-table commit path (CatalogHandlerUtils.commit).
  • Add equivalent handling in the multi-table commitTransaction path (IcebergCatalogHandler.commitTransaction).
  • Add targeted tests asserting retryable validation failures do not leak as ValidationException.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java Wraps RetryableValidationException from update application to avoid mapping to HTTP 400.
runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java Adds RetryableValidationException handling in commitTransaction update application loop.
runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractLocalIcebergCatalogTest.java Adds unit-style test ensuring CatalogHandlerUtils.commit surfaces retryable validation as CommitFailedException.
runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/CommitTransactionTest.java Adds REST-level test ensuring commitTransaction surfaces retryable validation as CommitFailedException.

Comment on lines +521 to +523
throw new ValidationFailureException(
new CommitFailedException(
e, "Validation failed, please retry: %s", e.getMessage()));

@ayushtkn ayushtkn Jul 24, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment above but this suggestion is wrong, Server-side retry won’t help because the stale sequence number is in the request payload itself; the client must refresh metadata and retry. This matches upstream Iceberg CatalogHandlers.commit()

https://github.com/apache/iceberg/blob/6976e020b894f6a6777704df2b8c4458cb291ae9/core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java#L641-L648

Comment on lines +1537 to +1541
} catch (RetryableValidationException e) {
// Surface as a retryable 409, matching CatalogHandlerUtils.commit.
throw new CommitFailedException(
e, "Validation failed, please retry: %s", e.getMessage());
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@ayushtkn
ayushtkn force-pushed the rety branch 4 times, most recently from 596ebee to 721e61f Compare July 24, 2026 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants