StripeClientBuilder throws an exception with null apiKey

Open
#2,012 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
java
Domain
api

Research direction

Start in src/main/java/com/stripe/StripeClient.java around the linked StripeClientBuilder.setApiKey implementation and follow the build() validation path. Check how a client without a global key obtains credentials from RequestOptions, then verify that construction succeeds with a null key and that calls using per-request keys behave as expected.

Written by the indexing model from the issue text.

Description

feature-request future
Describe the bug

When initializing StripeClient using StripeClient.builder(), providing a null value for the API key via .setApiKey(null) is allowed by the builder's interface. However, calling .build() on this builder results in an IllegalArgumentException because a global API key is expected at build time.

In a multi-tenant environment, it's common to use a single StripeClient instance and provide the specific tenant's API key with each request using RequestOptions.builder().setApiKey("sk_..."). In such scenarios, a global API key for the StripeClient itself is not necessary and might even be undesirable.

Currently, the SDK mandates a non-null API key during StripeClient construction, even if RequestOptions will be used for every subsequent API call.

To Reproduce

Attempt to build a StripeClient with a null API key:

try {
    StripeClient client = StripeClient.builder()
        .setApiKey(null) // Explicitly setting null, or not calling setApiKey if it defaults to null internally and is checked
        .build();
    // Potentially make a call, though the build() itself might fail
    // CustomerCollection customers = client.customers().list(RequestOptions.builder().setApiKey("sk_test_specific_tenant").build());
} catch (Exception e) {
    e.printStackTrace(); // Observe the exception during build()
}
Expected behavior

It should be possible to construct a StripeClient instance without a globally configured API key (i.e., with apiKey being null or not set on the builder) if the intention is to always provide the API key per request via RequestOptions.

The StripeClient.build() method should not throw an exception if no global API key is provided, and the responsibility for providing the API key should then fall entirely on the RequestOptions for each API call. If an API call is made without an API key in RequestOptions (and no global key is set), then an exception at that point would be appropriate.

Code snippets

OS

macOS

Java version

Java 21

stripe-java version

29.0.0

API version

2025-03-31.basil

Additional context

StripeClientBuilder.setApiKey does handle null apiKey so I don't get it why it's not accepted when the client is build.
https://github.com/stripe/stripe-java/blob/d177cbc62bb595399e298288fe9803c1d213a3ac/src/main/java/com/stripe/StripeClient.java#L519-L526

Dominant language
Java
Stars
1k
Forks
406
Avg merge
2d 18h
Merged PRs (30d)
20

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stripe/stripe-java

All issues in stripe/stripe-java

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.