Apache Polaris

Jul 8, 2026 min read

Apache Polaris is an open source, REST-compatible catalog for Apache Iceberg — designed to work across engines including Apache Spark, Apache Flink, Trino, and others through a unified catalog API.

7 pull requests merged across thread safety, core correctness, and codebase hygiene.


Thread Safety — InMemoryBufferEventListener

Three contributions addressing concurrency correctness in the in-memory event buffer, surfaced and fixed in sequence.

Give the in-memory event buffer its own lock

PR #4577Merged June 2026

Follow-up to PR #4498. The prior fix synchronized onComplete() against UnicastProcessor’s intrinsic lock — which worked only because Mutiny’s UnicastProcessor.onNext() happened to be synchronized. As @adutra noted, this leaned on a Mutiny implementation detail that could silently break in a future version.

This PR gives InMemoryBufferEventListener its own dedicated lock: an EventProcessor wrapper that holds a ReentrantLock and routes both onNext and onComplete through it. No longer dependent on how Mutiny locks internally. Also adds a reset() method so tests can reuse the bean after shutdown().

Synchronize onComplete calls in InMemoryBufferEventListener

PR #4498Merged May 2026

UnicastProcessor.onNext() is declared public synchronized void in smallrye-mutiny, but onComplete() is not synchronized. A concurrent processEvent (onNext) and eviction-driven onComplete on the same processor had no mutual exclusion — silently dropping events at the eviction boundary.

Wraps both onComplete() call sites (Caffeine eviction listener and shutdown() loop) in synchronized (processor) blocks, acquiring the same intrinsic monitor that onNext() uses.

Synchronize processEvent to satisfy Reactive Streams rule 1.3

PR #4487Merged May 2026

Fixes the concurrent onNext() race in InMemoryBufferEventListener.processEvent originally tracked in issue #2568. Reactive Streams rule 1.3 requires onNext to be called sequentially; Mutiny’s UnicastProcessor relies on that contract and concurrent emissions can silently drop events.

Synchronizes on the processor in processEvent so concurrent calls for the same realm serialize. Adds InMemoryBufferEventListenerThreadSafetyTest — 10 threads × 100 events against the same realm via a CountDownLatch barrier, asserting all 1000 events land in the events table.


Core Correctness

Validate default-base-location against storage config on catalog update

PR #4422Merged July 2026

Adds validation to reject catalog updates where the new default-base-location falls outside the catalog’s configured allowedLocations. Previously, updating the base location without updating the storage config was silently accepted — but subsequent namespace and table creation would fail because the new location wasn’t in the allowed paths.

Adds validateBaseLocationAgainstStorageConfig() in PolarisAdminService.updateCatalog() — clear error at update time rather than a silent failure downstream.

Extract shared credential rotation pre-condition check

PR #4420Merged June 2026

Extracts the duplicated PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_STATE pre-condition check from PolarisAuthorizerImpl and RangerPolarisAuthorizer into a shared AuthorizationPreConditions utility class. Both authorizers had identical logic to block non-ROTATE_CREDENTIALS operations when a principal is flagged for mandatory credential rotation.


Documentation and Codebase Hygiene

Fix various typos across docs, code, and tooling

PR #4520Merged May 2026

7 typo fixes across docs, Java source, shell scripts, and Helm chart tests — including a duplicate-word in a Micrometer metric description visible in ops dashboards.

Remove duplicate ‘for’ in markdown_testing.py

PR #4514Merged May 2026

Removes duplicate “for” from a CI tooling print statement in the site integration test runner.