bumptech/glide · error · IllegalArgumentException

RequestOptionsExtensions must be public, including: {}

Error message

RequestOptionsExtensions must be public, including: {}

What it means

A @GlideExtension class must be public because Glide generates code that references its static methods from the produced RequestOptions/RequestManager subclasses. GlideExtensionValidator.validateExtension checks typeElement.getModifiers().contains(Modifier.PUBLIC) first and rejects anything less visible. Non-public, package-private, internal (Kotlin) or nested-non-public classes all fail.

Source

Thrown at annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/GlideExtensionValidator.java:51

 * for an Application.
 */
final class GlideExtensionValidator {
  private final ProcessingEnvironment processingEnvironment;
  private final ProcessorUtil processorUtil;
  private final boolean useLegacyTypeComparison;

  GlideExtensionValidator(
      ProcessingEnvironment processingEnvironment,
      ProcessorUtil processorUtil,
      boolean useLegacyTypeComparison) {
    this.processingEnvironment = processingEnvironment;
    this.processorUtil = processorUtil;
    this.useLegacyTypeComparison = useLegacyTypeComparison;
  }

  void validateExtension(TypeElement typeElement) {
    if (!typeElement.getModifiers().contains(Modifier.PUBLIC)) {
      throw new IllegalArgumentException(
          "RequestOptionsExtensions must be public, including: " + getName(typeElement));
    }
    for (Element element : typeElement.getEnclosedElements()) {
      if (element.getKind() == ElementKind.CONSTRUCTOR) {
        validateExtensionConstructor(element);
      } else if (element.getKind() == ElementKind.METHOD) {
        ExecutableElement executableElement = (ExecutableElement) element;
        if (executableElement.getAnnotation(GlideOption.class) != null) {
          validateGlideOption(executableElement);
        } else if (executableElement.getAnnotation(GlideType.class) != null) {
          validateGlideType(executableElement);
        }
      }
    }
  }

  private static String getQualifiedMethodName(ExecutableElement executableElement) {
    return getEnclosingClassName(executableElement) + "#" + getName(executableElement);

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Make the @GlideExtension class `public` (Java: `public class`; Kotlin: top-level `class` — Kotlin classes are public by default, so remove any `private`/`internal`).
  2. If the class is nested, ensure both the outer and inner class are public, or move it to a top-level class.
  3. Recompile to confirm validateExtension passes (the validator runs before any method-level checks).

Example fix

// before
@GlideExtension
internal class MyGlideExtension { ... }   // Kotlin

// after
@GlideExtension
class MyGlideExtension { ... }
Defensive patterns

Strategy: validation

Validate before calling

@Test void glideExtensionIsPublic() {
  int mods = MyGlideExtension.class.getModifiers();
  assertTrue("@GlideExtension class must be public", java.lang.reflect.Modifier.isPublic(mods));
}

Prevention

When it happens

Trigger: GlideExtensionValidator.validateExtension runs for every class annotated with @GlideExtension; if the modifiers omit PUBLIC it throws. Hit by a Kotlin `internal class`, a package-private Java class, or a non-public nested class carrying @GlideExtension.

Common situations: Kotlin extension written as `class` or `internal class` instead of `class` with `public`; refactoring that dropped the `public` modifier; placing the @GlideExtension on a private nested utility class.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/e4b87ee8c01efc93. Report an issue: GitHub.