google/gson · error · RuntimeException

Unexpected IllegalAccessException occurred

Error message

Unexpected IllegalAccessException occurred (Gson {}). Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If you are not using ReflectionAccessFilter, report this to the Gson maintainers.

What it means

Thrown by ReflectionHelper.createExceptionForUnexpectedIllegalAccess when reflection on a field produces an IllegalAccessException that the ReflectionAccessFilter machinery cannot handle. The message notes that certain ReflectionAccessFilter features need Java >= 9, and asks non-users of ReflectionAccessFilter to report the bug to Gson maintainers. This is a defensive 'this should never happen' path.

Solutions

  1. If on Java 8, either upgrade to Java 9+ or remove/disable the ReflectionAccessFilter that requires it.
  2. Ensure the ReflectionAccessFilter you configured actually permits access for the affected type.
  3. Register a custom TypeAdapter/InstanceCreator for the failing type to bypass reflection entirely.
  4. If you are not using ReflectionAccessFilter, capture the full stack trace and Gson version and report to the Gson maintainers as the message instructs.

Example fix

// before: ReflectionAccessFilter configured on Java 8 -> unexpected IllegalAccessException
Gson g = new GsonBuilder()
  .addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_PLATFORM)
  .create();

// after: drop the filter on Java 8, or move to Java 9+
Gson g = new GsonBuilder().create(); // no filter

// or supply a custom InstanceCreator to avoid reflection:
Gson g = new GsonBuilder()
  .registerTypeAdapter(MyType.class, (InstanceCreator<MyType>) t -> new MyType())
  .create();
Defensive patterns

Strategy: try-catch

Validate before calling

// verify JVM version suitability before enabling filter features
if (ReflectionAccessFilter.class.getModule().isNamed() && Runtime.version().feature() < 9) {
  throw new IllegalStateException("ReflectionAccessFilter features require Java >= 9");
}

Try / catch

try {
  return gson.fromJson(json, Type.class);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("Unexpected IllegalAccessException occurred")) {
    // remove ReflectionAccessFilter or upgrade JVM; do NOT silently retry the same Gson
    throw new IllegalStateException("ReflectionAccessFilter/JVM mismatch", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: A configured ReflectionAccessFilter is in use, but the JVM is older than Java 9 (where the filter relies on APIs that do not exist), or a field access fails in an unexpected way not covered by the filter's allowance logic. Also possible on early-access or buggy JDKs.

Common situations: Running on Java 8 with a ReflectionAccessFilter configured for Java 9+ semantics; custom ReflectionAccessFilter implementations that mishandle field access; obscure JDK reflection bugs; mismatched Gson version expecting features the JVM lacks.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/3806a9e6889872ea. Report an issue: GitHub.

Appendix: source

Thrown at gson/src/main/java/com/google/gson/internal/reflect/ReflectionHelper.java:201

    return RECORD_HELPER.isRecord(raw);
  }

  public static String[] getRecordComponentNames(Class<?> raw) {
    return RECORD_HELPER.getRecordComponentNames(raw);
  }

  /** Looks up the record accessor method that corresponds to the given record field */
  public static Method getAccessor(Class<?> raw, Field field) {
    return RECORD_HELPER.getAccessor(raw, field);
  }

  public static <T> Constructor<T> getCanonicalRecordConstructor(Class<T> raw) {
    return RECORD_HELPER.getCanonicalRecordConstructor(raw);
  }

  public static RuntimeException createExceptionForUnexpectedIllegalAccess(
      IllegalAccessException exception) {
    throw new RuntimeException(
        "Unexpected IllegalAccessException occurred (Gson "
            + GsonBuildConfig.VERSION
            + "). Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If"
            + " you are not using ReflectionAccessFilter, report this to the Gson maintainers.",
        exception);
  }

  private static RuntimeException createExceptionForRecordReflectionException(
      ReflectiveOperationException exception) {
    throw new RuntimeException(
        "Unexpected ReflectiveOperationException occurred"
            + " (Gson "
            + GsonBuildConfig.VERSION
            + ")."
            + " To support Java records, reflection is utilized to read out information"
            + " about records. All these invocations happens after it is established"
            + " that records exist in the JVM. This exception is unexpected behavior.",
        exception);

View on GitHub (pinned to 310ac341f2)