google/gson · error · JsonIOException
ReflectionAccessFilter does not permit using reflection for
Error message
ReflectionAccessFilter does not permit using reflection for " + raw + ". Register a TypeAdapter for this type or adjust the access filter.
What it means
Thrown by ReflectiveTypeAdapterFactory.create() as a JsonIOException when a registered ReflectionAccessFilter returns FilterResult.BLOCK_ALL for the type being adapted. Gson refuses to use reflection (field access) for that class and requires either an explicit TypeAdapter or an adjustment to the filter. This is a security-hardening mechanism to prevent reflection on sensitive types.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:145
return null;
}
@Override
public void write(JsonWriter out, T value) throws IOException {
out.nullValue();
}
@Override
public String toString() {
return "AnonymousOrNonStaticLocalClassAdapter";
}
};
}
FilterResult filterResult =
ReflectionAccessFilterHelper.getFilterResult(reflectionFilters, raw);
if (filterResult == FilterResult.BLOCK_ALL) {
throw new JsonIOException(
"ReflectionAccessFilter does not permit using reflection for "
+ raw
+ ". Register a TypeAdapter for this type or adjust the access filter.");
}
boolean blockInaccessible = filterResult == FilterResult.BLOCK_INACCESSIBLE;
// If the type is actually a Java Record, we need to use the RecordAdapter instead. This will
// always be false on JVMs that do not support records.
if (ReflectionHelper.isRecord(raw)) {
@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);View on GitHub (pinned to 8b8628c656)
Solutions
- Register a custom TypeAdapter (or JsonSerializer/JsonDeserializer) for the blocked type via GsonBuilder.registerTypeAdapter(...).
- Adjust the ReflectionAccessFilter to return ALLOW for this type, or BLOCK_INACCESSIBLE instead of BLOCK_ALL if partial reflection is acceptable.
- Annotate the type with @JsonAdapter(SomeAdapter.class) so Gson uses your adapter without reflection.
- Narrow the filter's scope so it only blocks the intended sensitive types.
Example fix
// before: filter blocks java.util.Currency, no adapter registered
Gson gson = new GsonBuilder()
.addReflectionAccessFilter((c, t) -> t.getName().startsWith("java.") ? FilterResult.BLOCK_ALL : FilterResult.ALLOW)
.create();
gson.toJson(myCurrency); // throws JsonIOException
// after: register an adapter for the blocked type
Gson gson = new GsonBuilder()
.addReflectionAccessFilter((c, t) -> t.getName().startsWith("java.") ? FilterResult.BLOCK_ALL : FilterResult.ALLOW)
.registerTypeAdapter(Currency.class, new CurrencyAdapter())
.create();
gson.toJson(myCurrency); Defensive patterns
Strategy: fallback
Validate before calling
// Provide a TypeAdapter for any type you block via ReflectionAccessFilter Gson gson = new GsonBuilder() .addReflectionAccessFilter((c, t) -> isBlocked(t) ? FilterResult.BLOCK_ALL : FilterResult.ALLOW) .registerTypeAdapter(MyBlockedType.class, new MyBlockedTypeAdapter()) .create();
Try / catch
try {
return gson.toJson(obj);
} catch (JsonIOException e) {
if (e.getMessage() != null && e.getMessage().contains("ReflectionAccessFilter does not permit")) {
// build a fresh Gson without the blocking filter, or with an adapter for the type
Gson fallback = buildGsonWithAdapterFor(obj.getClass());
return fallback.toJson(obj);
}
throw e;
} Prevention
- For every type a ReflectionAccessFilter blocks, register an explicit TypeAdapter.
- Prefer BLOCK_INACCESSIBLE over BLOCK_ALL when you only need to avoid setAccessible on internals.
- Document the filter policy and the adapters required for blocked types in your project.
When it happens
Trigger: Registering a ReflectionAccessFilter via GsonBuilder.addReflectionAccessFilter(...) that blocks a type, then attempting to serialize/deserialize that type (or a type whose fields reference it) without a custom TypeAdapter. The filter's filterCheck returns BLOCK_ALL and Gson has no other adapter to fall back to.
Common situations: Security reviews that add filters blocking platform or internal classes; blocking third-party library types that the model transitively references; overly-broad filters (e.g. blocking all java.* or a package) catching application types; upgrading Gson and adopting the reflection filter feature without providing adapters for blocked types.
Related errors
- Unexpected {peeked} when reading a JsonElement.
- memberDescription + " is not accessible and ReflectionAccess
- ReflectionAccessFilter does not permit using reflection for
- GSON ({GsonBuildConfig.VERSION}) cannot handle {type}
- Class {typeAdapter.getClass().getName()} does not implement
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/2b82a67a0563804f.json.
Report an issue: GitHub.