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 restrictions

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Register a TypeAdapter for the concrete subtype so the reflective hierarchy walk is skipped.
  2. Adjust the filter to return ALLOW or BLOCK_INACCESSIBLE instead of BLOCK_ALL for the supertype.
  3. Move the inherited fields into a type the filter permits, or flatten the hierarchy.
  4. 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

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


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/a7e0864593a73203.json. Report an issue: GitHub.