google/gson · error · JsonIOException
memberDescription + " is not accessible and ReflectionAccess
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
Thrown by checkAccessible() when a ReflectionAccessFilter returned BLOCK_INACCESSIBLE for a type and a specific field, accessor method, or constructor cannot be reached by the calling code without making it accessible. Gson refuses to call setAccessible(true) when the filter forbids it, so serialization or deserialization of that member aborts with a JsonIOException. The error is not about Java module visibility per se, but about the access policy the filter established.
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 8b8628c656)
Solutions
- Register a custom TypeAdapter for the declaring type so Gson does not fall back to reflection for it.
- Loosen the ReflectionAccessFilter to return ALLOW for that specific type/class, or remove the BLOCK_INACCESSIBLE filter.
- Increase visibility of the field (or its class) to public so no setAccessible is required.
- Add `opens` directive for the package in module-info.java (JPMS) so reflective deep access is permitted.
- For records, ensure the canonical constructor is at least package-accessible and the filter permits it.
Example fix
// before
Gson gson = new GsonBuilder()
.addReflectionAccessFilter((c) -> FilterResult.BLOCK_INACCESSIBLE)
.create();
gson.toJson(internalPackageObject); // throws
// after: allow this specific type
.addReflectionAccessFilter((c) ->
c.getType() == MyType.class ? FilterResult.ALLOW : FilterResult.BLOCK_INACCESSIBLE)
// or register an adapter
.registerTypeAdapter(MyType.class, new MyTypeAdapter()) Defensive patterns
Strategy: validation
Validate before calling
// Before building Gson, verify the filter allows your types
Class<?> target = MyType.class;
FilterResult r = myFilter.apply(new ReflectionAccessFilter.FilterContext(target));
if (r == FilterResult.BLOCK_INACCESSIBLE) {
Field f = target.getDeclaredField("sensitiveField");
if (!ReflectionAccessFilterHelper.canAccess(f, null)) {
throw new IllegalStateException("Will fail: " + f + " is inaccessible under filter");
}
} Type guard
null
Try / catch
try {
gson.toJson(obj);
} catch (JsonIOException e) {
if (e.getMessage().contains("is not accessible and ReflectionAccessFilter")) {
// fall back to a manually-registered adapter or skip the field
log.warn("Access blocked for {}", obj.getClass(), e);
} else throw e;
} Prevention
- Keep a whitelist of types allowed for reflection and register adapters for everything else.
- Document each ReflectionAccessFilter's intent in the GsonBuilder construction.
- Test serialization of every type reachable from your public API under the production filter.
- Prefer registering TypeAdapters over relying on deep reflection for third-party types.
When it happens
Trigger: Occurs when a ReflectionAccessFilter is registered on GsonBuilder (addReflectionAccessFilter) returning FilterResult.BLOCK_INACCESSIBLE, and the target class has private/package-private fields (or an inaccessible record constructor) that Gson then tries to read/write reflectively. Fires from BoundField.write (line 225/229), readIntoField (line 277), or RecordAdapter constructor (line 586).
Common situations: Common on JPMS modular projects where types in another module are not exported; library hardening configs that blanket-block inaccessible members; serializing third-party library classes whose fields are private with no public accessors; mixing records with non-public canonical constructors under a restrictive filter.
Related errors
- ReflectionAccessFilter does not permit using reflection for
- ReflectionAccessFilter does not permit using reflection for
- Failed making " + description + " accessible; either increas
- Primitive type is not allowed
- Must specify owner type for {rawType}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/a43c23aab24fd83b.json.
Report an issue: GitHub.