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
Thrown when a ReflectionAccessFilter returns BLOCK_ALL for a supertype encountered while scanning inherited fields of a subtype. Unlike the BLOCK_INACCESSIBLE case, this fully prohibits any reflection on that supertype, so Gson cannot even enumerate its fields. Raised as a JsonIOException in getBoundFields (line 340).
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 8b8628c656)
Solutions
- Register a TypeAdapter for the concrete subtype so the reflective hierarchy walk is skipped.
- Adjust the filter to return ALLOW or BLOCK_INACCESSIBLE instead of BLOCK_ALL for the supertype.
- Move the inherited fields into a type the filter permits, or flatten the hierarchy.
- Compose the object with a separate DTO instead of inheriting from a restricted base class.
Example fix
// before
.addReflectionAccessFilter((c) ->
c.getType().getPackage().getName().startsWith("com.lib.")
? FilterResult.BLOCK_ALL : FilterResult.ALLOW)
// serializing subclass of com.lib.Base throws
// after: allow or register adapter
.registerTypeAdapter(MySub.class, new MySubAdapter()) Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that no supertype of T is BLOCK_ALL
for (Class<?> s = T.class.getSuperclass(); s != null && s != Object.class; s = s.getSuperclass()) {
FilterResult r = myFilter.apply(new ReflectionAccessFilter.FilterContext(s));
if (r == FilterResult.BLOCK_ALL && s.getDeclaredFields().length > 0) {
throw new IllegalStateException("Supertype blocked: " + s);
}
} Type guard
null
Try / catch
try {
gson.toJson(obj);
} catch (JsonIOException e) {
if (e.getMessage().contains("(supertype of")) {
// register adapter for obj.getClass() and retry
} else throw e;
} Prevention
- Register TypeAdapters for any subclass of a framework base class.
- Document the filter policy and which packages are blocked.
- Avoid inheriting from restricted third-party classes in serialized models.
- Use composition (DTO wrapping) instead of inheritance from blocked types.
When it happens
Trigger: A subclass is being serialized/deserialized and Gson walks up to a parent class for which a registered ReflectionAccessFilter returns FilterResult.BLOCK_ALL. Triggered only when the supertype declares at least one field (fields.length > 0) at line 336.
Common situations: Security hardening that blocks reflection on framework base classes (e.g., java.*, javax.*, Spring proxies); JPMS setups blocking access to external module types in the hierarchy; serialization of generated/interceptor subclasses whose parent lives in a restricted library.
Related errors
- ReflectionAccessFilter does not permit using reflection for
- memberDescription + " is not accessible and ReflectionAccess
- Primitive type is not allowed
- Must specify owner type for {rawType}
- At most one lower bound is supported
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/a7e0864593a73203.json.
Report an issue: GitHub.