google/gson · error · JsonIOException
${memberDescription} is not accessible and ReflectionAccessF
Error message
${memberDescription} is not accessible and ReflectionAccessFilter does not permit making it accessible. Register a TypeAdapter for the declaring type, adjust the access filter or increase the visibility of the element and its declaring type. What it means
When a ReflectionAccessFilter returns BLOCK_INACCESSIBLE, Gson will not call setAccessible(true) on fields/constructors. checkAccessible() then verifies the member is accessible under normal Java access rules; if it is not (e.g. a private field in a non-exported package, or an inaccessible record constructor), it throws JsonIOException. This respects Java module encapsulation (JPMS) and access boundaries rather than forcing accessibility.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:173
@SuppressWarnings("unchecked")
TypeAdapter<T> adapter =
(TypeAdapter<T>)
new RecordAdapter<>(
raw, getBoundFields(gson, type, raw, blockInaccessible, true), blockInaccessible);
return adapter;
}
ObjectConstructor<T> constructor = constructorConstructor.get(type, true);
return new FieldReflectionAdapter<>(
constructor, getBoundFields(gson, type, raw, blockInaccessible, false));
}
private static <M extends AccessibleObject & Member> void checkAccessible(
Object object, M member) {
if (!ReflectionAccessFilterHelper.canAccess(
member, Modifier.isStatic(member.getModifiers()) ? null : object)) {
String memberDescription = ReflectionHelper.getAccessibleObjectDescription(member, true);
throw new JsonIOException(
memberDescription
+ " is not accessible and ReflectionAccessFilter does not permit making it"
+ " accessible. Register a TypeAdapter for the declaring type, adjust the access"
+ " filter or increase the visibility of the element and its declaring type.");
}
}
private BoundField createBoundField(
Gson context,
Field field,
Method accessor,
String serializedName,
TypeToken<?> fieldType,
boolean serialize,
boolean blockInaccessible) {
boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
View on GitHub (pinned to 310ac341f2)
Solutions
- Register a custom TypeAdapter for the declaring type so reflection on its fields is unnecessary
- Change the ReflectionAccessFilter to ALLOW for that type (if acceptable under your security model)
- Increase visibility of the element and its declaring type (make the field/package-accessible, or add 'opens' in module-info for JPMS)
- Annotate the field with @JsonAdapter to supply a non-reflective adapter
Example fix
// before - private field inaccessible under BLOCK_INACCESSIBLE
class Box { private int secret; }
gson.fromJson(json, Box.class); // throws
// after option 1 - widen visibility
class Box { int secret; }
// after option 2 - register a TypeAdapter
Gson gson = new GsonBuilder()
.registerTypeAdapter(Box.class, new BoxAdapter())
.create(); Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check field accessibility before relying on reflective (de)serialization
Field f = MyType.class.getDeclaredField("secret");
boolean accessible = Modifier.isPublic(f.getModifiers())
|| (f.canAccess(instance));
if (!accessible) {
throw new IllegalStateException("Field not accessible under BLOCK_INACCESSIBLE: " + f);
} Type guard
// Confirm a member is accessible under current access rules
static boolean isAccessible(Field f, Object instance) {
try {
return f.canAccess(instance);
} catch (Exception e) {
return false;
}
} Try / catch
try {
MyType obj = gson.fromJson(json, MyType.class);
} catch (com.google.gson.JsonIOException e) {
// '... is not accessible...': widen visibility, open the package (JPMS), or register a TypeAdapter
} Prevention
- Widen field/package visibility or add 'opens' in module-info for types you control
- Register a TypeAdapter for types whose members cannot be made accessible
- Prefer records with accessible components, or annotate fields with @JsonAdapter
When it happens
Trigger: Deserializing a type with private/inaccessible fields under a BLOCK_INACCESSIBLE filter; serializing records whose accessor/constructor is not accessible; JPMS strong encapsulation (Java 16+ default) denying access to a package.
Common situations: Java 16+ with strong encapsulation; modules that do not 'opens' their packages to Gson; library types with restrictive visibility; switching a filter from ALLOW to BLOCK_INACCESSIBLE.
Related errors
- ReflectionAccessFilter does not permit using reflection for
- Unable to create instance of ${rawType}; ReflectionAccessFil
- ReflectionAccessFilter does not permit using reflection for
- Unable to invoke no-args constructor of ${rawType}; construc
- Failed invoking canAccess
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/4ac13052a3b0de92.
Report an issue: GitHub.