Skip to content

[BUG] Converting TransportOptions may throw NPE if queryParameters() is null #1887

@baekgyu-kim

Description

@baekgyu-kim

What is the bug?

ApacheHttpClient5Options.of(...) and RestClientOptions.of(...) assume TransportOptions.queryParameters() is non-null.
Both methods call .forEach(...) directly.
If queryParameters() returns null, they throw NullPointerException.

How can one reproduce the bug?

  1. Create a TransportOptions implementation where queryParameters() returns null.
  2. Call ApacheHttpClient5Options.of(customOptions) or RestClientOptions.of(customOptions).
  3. NullPointerException is thrown.

What is the expected behavior?

Both methods should handle null query parameters as empty parameters and not throw.

Do you have any additional context?

options == null is already guarded by call sites, so this issue is not about null options:

  • ApacheHttpClient5Transport.java:141
  • ApacheHttpClient5Transport.java:177
  • RestClientTransport.java:109
  • RestClientTransport.java:201

options.headers() is effectively non-null in built-in implementations:

  • TransportOptions.DefaultImpl always initializes headers to an empty/non-empty list:
    TransportOptions.java:139
  • headers() returns that list directly:
    TransportOptions.java:145
  • ApacheHttpClient5Options.headers() and RestClientOptions.headers() both return collected lists, not null:
    ApacheHttpClient5Options.java:68
    RestClientOptions.java:88

However, the parameter map (queryParameters()) can be null today:

  • ApacheHttpClient5Options.java:73
  • RestClientOptions.java:96

And both conversion methods call .forEach(...) on it without a null check:

  • ApacheHttpClient5Options.java:229
  • RestClientOptions.java:66

So the concrete NPE source in this issue is queryParameters() == null, not options == null.
As a defensive hardening step, we can also guard against options == null and options.headers() == null in these conversion methods, even though they are not the primary failure path in this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions