S3 Backed Polaris - loadTable endpoint throws misleading error message on manually deleted table
- 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
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