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
- If on Java 8, either upgrade to Java 9+ or remove/disable the ReflectionAccessFilter that requires it.
- Ensure the ReflectionAccessFilter you configured actually permits access for the affected type.
- Register a custom TypeAdapter/InstanceCreator for the failing type to bypass reflection entirely.
- 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
- Do not configure a ReflectionAccessFilter on Java 8.
- Pin Gson + JVM versions together in CI and run a reflection smoke test.
- Provide InstanceCreators for sensitive types to avoid reflection entirely.
- If this fires, capture the full stack trace and report per the message.
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
- Unexpected ReflectiveOperationException occurred
- At most one lower bound is supported
- Exactly one upper bound must be specified
- Failed invoking canAccess
- Failed making accessible; either increase its visibility or…
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)