Skip to content

Fix NPE in S3PinotFS credential refresh when initialized with a provided S3Client#18644

Closed
noob-se7en wants to merge 1 commit into
apache:masterfrom
noob-se7en:fix/s3pinotfs-init-s3config-npe
Closed

Fix NPE in S3PinotFS credential refresh when initialized with a provided S3Client#18644
noob-se7en wants to merge 1 commit into
apache:masterfrom
noob-se7en:fix/s3pinotfs-init-s3config-npe

Conversation

@noob-se7en
Copy link
Copy Markdown
Contributor

Problem

S3PinotFS.init(S3Client, String, PinotConfiguration) (the "bring your own client" overload) sets _s3Client but leaves the _s3Config field null. It constructs an S3Config only as a local variable, used for the server-side-encryption / multipart / ACL setup. The single-arg init(PinotConfiguration) is currently the only method that assigns the _s3Config field.

Any later operation that goes through the credential-refresh path — retryWithS3CredentialRefresh(...)initOrRefreshS3Client() — reads _s3Config.getRegion(). For an instance initialized with a caller-provided client, _s3Config is still null, so the first credential refresh throws a NullPointerException.

Fix

Assign the S3Config that the three-arg init already constructs to the _s3Config field (and reuse it for the existing SSE/multipart/ACL calls). No extra object construction. The field is now populated, so a later refresh rebuilds the client from the same config instead of NPEing.

Testing

Adds S3PinotFSInitTest.testInitWithProvidedClientPopulatesConfigForRefresh: initializes via the three-arg init, then calls initOrRefreshS3Client(). It reproduces the NullPointerException before this change and passes after. Static credentials keep the rebuild fully offline (no S3 mock container required).

…ded S3Client

`S3PinotFS.init(S3Client, String, PinotConfiguration)` set `_s3Client` but left
the `_s3Config` field null — it built an `S3Config` only as a local for the
server-side-encryption / multipart / ACL setup. The single-arg
`init(PinotConfiguration)` is the only path that assigned `_s3Config`.

Any later operation routed through `retryWithS3CredentialRefresh(...)` ->
`initOrRefreshS3Client()` reads `_s3Config.getRegion()`, so an instance created
with a caller-provided client threw a NullPointerException on the first
credential refresh.

Assign the already-constructed `S3Config` to the `_s3Config` field (and reuse it
for the SSE/multipart/ACL setup). No extra object construction; the field is now
populated so a refresh rebuilds the client from the same config instead of
NPEing.

Adds `S3PinotFSInitTest` which initializes via the three-arg `init` and then
calls `initOrRefreshS3Client()` — it reproduces the NPE before this change and
passes after. Static credentials keep the rebuild fully offline (no container).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@noob-se7en noob-se7en added bug Something is not working as expected pinot-filesystem Related to PinotFS abstraction (S3, GCS, ADLS, HDFS) labels Jun 1, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.42%. Comparing base (a6463d4) to head (0e014e5).
⚠️ Report is 58 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #18644      +/-   ##
============================================
+ Coverage     64.27%   64.42%   +0.14%     
- Complexity     1137     1299     +162     
============================================
  Files          3314     3362      +48     
  Lines        204064   207907    +3843     
  Branches      31760    32463     +703     
============================================
+ Hits         131165   133945    +2780     
- Misses        62373    63180     +807     
- Partials      10526    10782     +256     
Flag Coverage Δ
custom-integration1 100.00% <ø> (ø)
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-21 64.42% <100.00%> (+0.14%) ⬆️
temurin 64.42% <100.00%> (+0.14%) ⬆️
unittests 64.42% <100.00%> (+0.14%) ⬆️
unittests1 56.79% <ø> (+0.07%) ⬆️
unittests2 37.17% <100.00%> (+1.62%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@xiangfu0 xiangfu0 left a comment

Choose a reason for hiding this comment

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

Found one high-signal issue; see inline comment.

// through initOrRefreshS3Client(), which reads _s3Config.getRegion(); leaving the field null
// caused a NullPointerException on the first refresh for instances initialized with a provided
// client.
_s3Config = new S3Config(serverSideEncryptionConfig);
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.

This fixes the init(S3Client, ..., PinotConfiguration) path, but the other public provided-client overload at init(S3Client) still leaves _s3Config null. If a caller uses that overload and later hits the 401/403 retry path, initOrRefreshS3Client() will still dereference _s3Config.getRegion() and fail before the retry happens. Please either initialize _s3Config there as well or explicitly guard/disable credential refresh for bare-client initialization.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I believe this is unrelated and can be as a followup.

@noob-se7en noob-se7en requested a review from xiangfu0 June 2, 2026 19:34
@noob-se7en
Copy link
Copy Markdown
Contributor Author

closing as duplicate #18679 was merged.

@noob-se7en noob-se7en closed this Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is not working as expected pinot-filesystem Related to PinotFS abstraction (S3, GCS, ADLS, HDFS)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants