Skip to content

Core: Validate default-base-location against storage config on catalog update#4422

Open
visit2rahul wants to merge 3 commits into
apache:mainfrom
visit2rahul:fix/validate-default-base-location-update
Open

Core: Validate default-base-location against storage config on catalog update#4422
visit2rahul wants to merge 3 commits into
apache:mainfrom
visit2rahul:fix/validate-default-base-location-update

Conversation

@visit2rahul
Copy link
Copy Markdown

Closes #4355

Summary

Adds validation to reject catalog updates where the new default-base-location is not within any of the allowedLocations configured in the catalog's existing storage configuration.

Previously, updating only the default-base-location property without also providing storageConfigInfo would leave the catalog in an inconsistent state — the property would be accepted but subsequent namespace and table creation would fail because the new location wasn't in allowedLocations.

Change

Added validateBaseLocationAgainstStorageConfig() in PolarisAdminService.updateCatalog() that checks the new base location is a child of at least one allowed storage location when the storage config itself is not being updated.

Scenario

  1. Catalog created with default-base-location=s3://foo/, allowedLocations=["s3://foo/"]
  2. Update catalog to default-base-location=s3://bar/ without updating storage config
  3. Before: Update accepted silently, namespace/table creation fails later
  4. After: Update rejected with clear error message

Test Plan

  • polaris-runtime-service:compileJava passes
  • polaris-runtime-service:test (admin tests) passes
  • Spotless and checkstyle pass

…g update (apache#4355)

Reject catalog updates where the new default-base-location is not
within any of the allowed locations in the existing storage configuration.

Previously, updating only the default-base-location property without
also updating storageConfigInfo would leave the catalog in an
inconsistent state where namespace and table creation would fail.

The fix adds a validation check in updateCatalog that verifies the
new base location is a child of at least one allowed location when
the storage config itself is not being updated.
}
}

private void validateBaseLocationAgainstStorageConfig(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: maybe worth to add a test on this path to verify.


// If the storage config is not being updated, validate that the new base location
// is allowed by the existing storage configuration to prevent inconsistent state.
if (updateRequest.getStorageConfigInfo() == null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe we can also check if the new location is different from the current one. It will accelerate and avoid any side effect.

Suggested change
if (updateRequest.getStorageConfigInfo() == null) {
if (updateRequest.getStorageConfigInfo() == null && !newDefaultBaseLocation.equals(currentCatalogEntity.getBaseLocation())) {

That could be done before defaultBaseLocation = newDefaultBaseLocation; also.

@visit2rahul
Copy link
Copy Markdown
Author

visit2rahul commented May 14, 2026

@jbonofre thanks for the review — addressed both points (latest in cc58e79):

  • L951 short-circuit (b3f807c) — added the && !newDefaultBaseLocation.equals(currentCatalogEntity.getBaseLocation()) guard before invoking the storage-config check.
  • L885 test — first pass (b3f807c) added a thin test that only exercised StorageLocation::isChildOf; on second look that wasn't really testing the validation path you asked about, so cc58e79 strengthens it: validateBaseLocationAgainstStorageConfig is made package-private static and BaseLocationValidationTest now invokes it directly with mocked CatalogEntity / PolarisStorageConfigurationInfo. Coverage:
    • child / exact-match locations accepted
    • location outside the allowed prefix rejected with BadRequestException (asserts catalog name + location + allowed list appear in the message)
    • multi-allowed-location acceptance
    • scheme-mismatch rejection
    • null storage config, null and empty allowed-locations are treated as no-op (matches the early-returns in the method)

Will look at the failing regression once CI re-runs.

…dation path

- Make validateBaseLocationAgainstStorageConfig package-private static for
  direct unit testing (no PolarisAdminService construction needed)
- Replace stub StorageLocation::isChildOf tests with tests that call the
  validation method directly, covering: child / exact match / outside-allowed
  rejection (BadRequestException with expected message), multi-allowed,
  scheme mismatch, null storage config, null/empty allowed locations
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.

Updating default-base-location can leave catalog storage configuration inconsistent

2 participants