square/retrofit · error · NullPointerException

gson == null

Error message

gson == null

What it means

NullPointerException thrown by GsonConverterFactory.create(Gson) when the supplied Gson instance is null (line 52). The factory stores the Gson instance to obtain TypeAdapters for every request/response conversion, so a null Gson is unusable and the constructor fails fast rather than NPE-ing later during a conversion.

Source

Thrown at retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonConverterFactory.java:52

 * buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this
 * instance} last to allow the other converters a chance to see their types.
 */
public final class GsonConverterFactory extends Converter.Factory {
  /**
   * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  /**
   * Create an instance using {@code gson} for conversion. Encoding to JSON and decoding from JSON
   * (when no charset is specified by a header) will use UTF-8.
   */
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson, false);
  }

  private final Gson gson;
  private final boolean streaming;

  private GsonConverterFactory(Gson gson, boolean streaming) {
    this.gson = gson;
    this.streaming = streaming;
  }

  /**
   * Return a new factory which streams serialization of request messages to bytes on the HTTP thread
   * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background
   * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on
   * one of OkHttp's background threads.
   */
  public GsonConverterFactory withStreaming() {

View on GitHub (pinned to d0b112dad0)

Solutions

  1. If you do not need custom Gson configuration, use the no-arg `GsonConverterFactory.create()` which builds a default Gson.
  2. Ensure the Gson instance is non-null before passing: initialize it eagerly or use `Objects.requireNonNull(gson, "gson")`.
  3. Fix the DI binding so the Gson bean is always provided (e.g. mark the bean non-optional in your framework).

Example fix

// before
Gson gson = config.maybeGson(); // returns null when unconfigured
Retrofit retrofit = new Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build();

// after
Retrofit retrofit = new Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create()) // default Gson
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// Validate before wiring the converter into Retrofit.
Gson gson = Objects.requireNonNull(config.buildGson(), "gson must not be null");
GsonConverterFactory factory = GsonConverterFactory.create(gson);

Try / catch

try {
  factory = GsonConverterFactory.create(gson);
} catch (NullPointerException e) {
  throw new IllegalStateException("Gson was not provided; falling back is disabled", e);
}

Prevention

When it happens

Trigger: Calling `GsonConverterFactory.create(gson)` where `gson` evaluates to null — e.g. a DI-provided Gson field that was never bound, a lazy initializer that returned null, or explicitly passing null.

Common situations: Dependency-injection misconfiguration (Gson bean missing or scoped incorrectly); a `getGson()` helper that can return null when config is absent; module wiring changed during a refactor; test setup forgetting to initialize the Gson field.

Related errors


AI-assisted analysis of square/retrofit@d0b112dad0 (2026-08-04). Data as JSON: /data/errors/029194c31e706c9a.json. Report an issue: GitHub.