grpc/grpc-java · error · UnsupportedOperationException

Unable to load OkHttpChannelProvider

Error message

Unable to load OkHttpChannelProvider

What it means

AndroidChannelBuilder's target-string constructor relies on the bundled OkHttp channel provider (OKHTTP_CHANNEL_PROVIDER) to delegate channel creation. If ServiceLoader failed to load OkHttpChannelBuilder's provider — usually because the grpc-okhttp dependency is missing from the APK — the builder throws UnsupportedOperationException("Unable to load OkHttpChannelProvider").

Source

Thrown at android/src/main/java/io/grpc/android/AndroidChannelBuilder.java:138

  }

  /**
   * Creates a new builder, which delegates to the given ManagedChannelBuilder.
   *
   * <p>The provided {@code builder} becomes "owned" by AndroidChannelBuilder. The caller should
   * not modify the provided builder and AndroidChannelBuilder may modify it. That implies reusing
   * the provided builder to build another channel may result with unexpected configurations. That
   * usage should be discouraged.
   *
   * @since 1.24.0
   */
  public static AndroidChannelBuilder usingBuilder(ManagedChannelBuilder<?> builder) {
    return new AndroidChannelBuilder(builder);
  }

  private AndroidChannelBuilder(String target) {
    if (OKHTTP_CHANNEL_PROVIDER == null) {
      throw new UnsupportedOperationException("Unable to load OkHttpChannelProvider");
    }
    delegateBuilder =
        InternalManagedChannelProvider.builderForTarget(OKHTTP_CHANNEL_PROVIDER, target);
  }

  private AndroidChannelBuilder(ManagedChannelBuilder<?> delegateBuilder) {
    this.delegateBuilder = Preconditions.checkNotNull(delegateBuilder, "delegateBuilder");
  }

  /**
   * Enables automatic monitoring of the device's network state.
   */
  public AndroidChannelBuilder context(Context context) {
    this.context = context;
    return this;
  }

  @Override

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Add the io.grpc:grpc-okhttp dependency to the Android build
  2. Keep ServiceLoader entries: ensure ProGuard/R8 keeps META-INF/services/io.grpc.ManagedChannelProvider (don't strip service files)
  3. Alternatively use AndroidChannelBuilder.usingBuilder(OkHttpChannelBuilder.forTarget(...)) which bypasses provider lookup
  4. Prefer the explicit usingBuilder(...) path in newer grpc-android versions, as forTarget(String) is deprecated

Example fix

// before
Channel channel = AndroidChannelBuilder.forTarget("dns:///example.com:443").build();
// after (build.gradle: implementation 'io.grpc:grpc-okhttp:1.x')
Channel channel = AndroidChannelBuilder
    .usingBuilder(OkHttpChannelBuilder.forTarget("dns:///example.com:443"))
    .build();
Defensive patterns

Strategy: fallback

Validate before calling

if (OKHTTP_CHANNEL_PROVIDER == null) {
  throw new IllegalStateException("grpc-okhttp not available: add io.grpc:grpc-okhttp dependency");
}

Type guard

null

Try / catch

try {
  return AndroidChannelBuilder.forTarget(target).build();
} catch (UnsupportedOperationException e) {
  // grpc-okhttp missing or stripped: add dependency or fix keep rules
  throw new IllegalStateException("Include io.grpc:grpc-okhttp and keep META-INF/services", e);
}

Prevention

When it happens

Trigger: Building a channel via AndroidChannelBuilder.forTarget(String) when grpc-okhttp is not on the classpath, or with ProGuard/R8 stripping OkHttpChannelProvider before ServiceLoader can instantiate it.

Common situations: Android apps missing the io.grpc:grpc-okhttp dependency, shrinker configs removing META-INF/services entries for the provider, or transitive dependency conflicts dropping okhttp classes.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/6960fe3268a30a11. Report an issue: GitHub.