google/gson · error · JsonIOException
ReflectionAccessFilter does not permit using reflection for
Error message
ReflectionAccessFilter does not permit using reflection for ${raw} (supertype of ${originalRaw}). Register a TypeAdapter for this type or adjust the access filter. What it means
Gson walks the full class hierarchy to discover inherited fields. If a ReflectionAccessFilter returns BLOCK_ALL for any supertype (not the immediate type — that is handled separately), Gson refuses to silently drop those inherited fields and throws JsonIOException instead.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:340
if (raw.isInterface()) {
return FieldsData.EMPTY;
}
Map<String, BoundField> deserializedFields = new LinkedHashMap<>();
// For serialized fields use a Map to track duplicate field names; otherwise this could be a
// List<BoundField> instead
Map<String, BoundField> serializedFields = new LinkedHashMap<>();
Class<?> originalRaw = raw;
while (raw != Object.class) {
Field[] fields = raw.getDeclaredFields();
// For inherited fields, check if access to their declaring class is allowed
if (raw != originalRaw && fields.length > 0) {
FilterResult filterResult =
ReflectionAccessFilterHelper.getFilterResult(reflectionFilters, raw);
if (filterResult == FilterResult.BLOCK_ALL) {
throw new JsonIOException(
"ReflectionAccessFilter does not permit using reflection for "
+ raw
+ " (supertype of "
+ originalRaw
+ "). Register a TypeAdapter for this type or adjust the access filter.");
}
blockInaccessible = filterResult == FilterResult.BLOCK_INACCESSIBLE;
}
for (Field field : fields) {
boolean serialize = includeField(field, true);
boolean deserialize = includeField(field, false);
if (!serialize && !deserialize) {
continue;
}
// The accessor method is only used for records. If the type is a record, we will read out
// values via its accessor method instead of via reflection. This way we will bypass the
// accessible restrictionsView on GitHub (pinned to 310ac341f2)
Solutions
- Register a custom TypeAdapter for the domain type so Gson never uses reflection for it
- Adjust the ReflectionAccessFilter to return ALLOW or BLOCK_INACCESSIBLE instead of BLOCK_ALL for the specific supertype
Example fix
// before
Gson gson = new GsonBuilder()
.addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_JAVA)
.create();
gson.toJson(myType); // throws if MyType extends a java.* class
// after — bypass reflection with a custom adapter
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyType.class, new MyTypeAdapter())
.addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_JAVA)
.create(); Defensive patterns
Strategy: validation
Validate before calling
// Before serializing, check if any supertype would be blocked by the filter
public static boolean isSupertypeBlocked(Class<?> type, ReflectionAccessFilter filter) {
Class<?> c = type;
while (c != Object.class) {
if (filter.check(c) == FilterResult.BLOCK_ALL) return true;
c = c.getSuperclass();
}
return false;
} Try / catch
try {
String json = gson.toJson(obj);
} catch (JsonIOException e) {
if (e.getMessage().contains("ReflectionAccessFilter does not permit")) {
// fall back to a manually registered TypeAdapter for this type
}
} Prevention
- Register custom TypeAdapters for types whose supertypes are blocked by a ReflectionAccessFilter
- Test serialization of all domain types after adding a ReflectionAccessFilter
- Use BLOCK_INACCESSIBLE instead of BLOCK_ALL when you only need to prevent illegal-access warnings
When it happens
Trigger: A domain class extends or implements a type blocked by a ReflectionAccessFilter (e.g., BLOCK_ALL_JAVA or a custom filter blocking java.* or platform types) and Gson needs to serialize or deserialize it reflectively.
Common situations: Security hardening with ReflectionAccessFilter.BLOCK_ALL_PLATFORM on a type that extends a JDK class; JPMS migration where a model class inherits from a blocked package.
Related errors
- ReflectionAccessFilter does not permit using reflection for
- ${memberDescription} is not accessible and ReflectionAccessF
- Unable to create instance of ${rawType}; ReflectionAccessFil
- Failed invoking canAccess
- cannot deserialize ${baseType} subtype named ${label}; did y
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/57ca6a0613665707.
Report an issue: GitHub.