apache / apache/polaris

S3 Backed Polaris - loadTable endpoint throws misleading error message on manually deleted table

Open
#1,260 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
2.1k
Forks
522
Avg merge
1d 22h
Merged PRs (30d)
137

Description

### Is your feature request related to a problem? Please describe.

Scenario:
1. User creates a table in s3-backed Polaris.
2. User deletes table manually on s3 bucket.
3. `SELECT * FROM ` throws, Polaris logs: `Handling runtimeException User: <...>/PolarisAwsCredentialsStorageIntegration is not authorized to perform: s3:ListBucket on resource: "..." because no session policy allows the s3:ListBucket action (Service: S3, Status Code: 403, Request ID: ..., Extended Request ID: ...)`

It appears s3 throws permission errors when the associated loadTable tries to access files (rootpointer) that do not exist.

### Describe the solution you'd like

It would be nice if the error message was a variant of "table was deleted", "file not found", etc.

Is this possible, or is Polaris limited by the exception s3 throws?

### Describe alternatives you've considered

_No response_

### Additional context

Client Side:
```
org.apache.iceberg.exceptions.ForbiddenException: Forbidden: User: .../PolarisAwsCredentialsStorageIntegration is not authorized to perform: s3:ListBucket on resource: "..." because no session policy allows the s3:ListBucket action (Service: S3, Status Code: 403, Request ID: ..., Extended Request ID: ...) (SDK Attempt Count: 1)
at org.apache.iceberg.rest.ErrorHandlers$DefaultErrorHandler.accept(ErrorHandlers.java:212)
at org.apache.iceberg.rest.ErrorHandlers$TableErrorHandler.accept(ErrorHandlers.java:118)
at org.apache.iceberg.rest.ErrorHandlers$TableErrorHandler.accept(ErrorHandlers.java:102)
at org.apache.iceberg.rest.HTTPClient.throwFailure(HTTPClient.java:224)
at org.apache.iceberg.rest.HTTPClient.execute(HTTPClient.java:308)
at org.apache.iceberg.rest.BaseHTTPClient.get(BaseHTTPClient.java:77)
at org.apache.iceberg.rest.RESTClient.get(RESTClient.java:97)
at org.apache.iceberg.rest.RESTSessionCatalog.loadInternal(RESTSessionCatalog.java:465)
at org.apache.iceberg.rest.RESTSessionCatalog.loadTable(RESTSessionCatalog.java:489)
at org.apache.iceberg.catalog.BaseSessionCatalog$AsCatalog.loadTable(BaseSessionCatalog.java:99)
at org.apache.iceberg.rest.RESTCatalog.loadTable(RESTCatalog.java:102)
```

Polaris Side
```
at org.apache.polaris.service.exception.IcebergExceptionMapper.toResponse(IcebergExceptionMapper.java:95)
at org.apache.polaris.service.exception.IcebergExceptionMapper.toResponse(IcebergExceptionMapper.java:67)
at org.jboss.resteasy.reactive.server.core.RuntimeExceptionMapper.mapException(RuntimeExceptionMapper.java:96)
at org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext.mapExceptionIfPresent(ResteasyReactiveRequestContext.java:361)
at org.jboss.resteasy.reactive.server.handlers.ExceptionHandler.handle(ExceptionHandler.java:15)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:150)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:638)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing the reported loadTable path through RESTSessionCatalog.loadTable and Polaris's IcebergExceptionMapper.java at line 95, then inspect how S3-backed metadata failures are mapped. Reproduce the manual S3 deletion scenario and confirm that SELECT reports a table- or file-not-found condition instead of the misleading s3:ListBucket authorization error.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, java
Domain
api, backend, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.