google/gson · error · RuntimeException
Failed invoking canAccess
Error message
Failed invoking canAccess
What it means
Thrown when Gson's Java 9+ access checker cannot invoke AccessibleObject.canAccess(Object) via reflection. The wrapper 'Failed invoking canAccess' re-throws the underlying reflective invocation failure as a RuntimeException because Gson needs to know whether a field/method is accessible before using it, and an unexpected exception from canAccess itself is unrecoverable. The {c} placeholder is not interpolated here; the message is literal and the original exception is attached as the cause.
Source
Thrown at gson/src/main/java/com/google/gson/internal/ReflectionAccessFilterHelper.java:98
private abstract static class AccessChecker {
static final AccessChecker INSTANCE;
static {
AccessChecker accessChecker = null;
// TODO: Ideally should use Multi-Release JAR for this version specific code
if (JavaVersion.isJava9OrLater()) {
try {
Method canAccessMethod =
AccessibleObject.class.getDeclaredMethod("canAccess", Object.class);
accessChecker =
new AccessChecker() {
@Override
public boolean canAccess(AccessibleObject accessibleObject, Object object) {
try {
return (Boolean) canAccessMethod.invoke(accessibleObject, object);
} catch (Exception e) {
throw new RuntimeException("Failed invoking canAccess", e);
}
}
};
} catch (NoSuchMethodException ignored) {
// OK: will assume everything is accessible
}
}
if (accessChecker == null) {
accessChecker =
new AccessChecker() {
@Override
public boolean canAccess(AccessibleObject accessibleObject, Object object) {
// Cannot determine whether object can be accessed, so assume it can be accessed
return true;
}
};
}View on GitHub (pinned to 8b8628c656)
Solutions
- If using JPMS, add the required opens, e.g. run with --add-opens java.base/java.lang=ALL-UNNAMED (and opens for every package containing reflected classes), or declare them in module-info.
- Check the attached cause in the stack trace to identify the exact reflective failure (IllegalAccessException vs SecurityException vs IllegalArgumentException) and address that root cause.
- Disable the module/SecurityManager restriction, or run on a standard JDK where canAccess is reachable.
- If you cannot fix the environment, register a custom ReflectionAccessFilter returning BLOCK_INCLUSIVE_ALTERNATIVES / SERIALIZABLE or avoid reflective field access by registering explicit TypeAdapters for the affected types.
Example fix
// before: java ... -jar app.jar (canAccess invoke fails under JPMS)
// after: grant reflective access at launch
java --add-opens java.base/java.util=ALL-UNNAMED \
--add-opens com.example.data/com.example.data.model=ALL-UNNAMED \
-jar app.jar Defensive patterns
Strategy: try-catch
Validate before calling
// Before reflective heavy use, sanity-check module access at startup
try {
java.lang.reflect.Method m = AccessibleObject.class.getDeclaredMethod("canAccess", Object.class);
Field f = MyClass.class.getDeclaredField("x");
m.invoke(f, new MyClass()); // will throw if access is blocked
} catch (Exception e) {
throw new IllegalStateException("Gson reflective access blocked; add the required --add-opens", e);
} Try / catch
try {
return gson.fromJson(json, MyClass.class);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Failed invoking canAccess")) {
throw new ConfigurationException("Gson cannot perform reflective access; launch JVM with --add-opens ...", e);
}
throw e;
} Prevention
- Document the required --add-opens entries in your launch script and Dockerfile.
- Prefer registering explicit TypeAdapter / InstanceCreator instances over relying on reflective field access.
- Run a startup self-test that triggers Gson reflection once so configuration failures surface at boot, not deep in a request.
When it happens
Trigger: Occurs on Java 9+ only. The static initializer found AccessibleObject.canAccess and built the Java9 AccessChecker, but at runtime canAccessMethod.invoke(accessibleObject, object) threw (e.g. IllegalAccessException after the calling module lost access, a SecurityManager denying reflect access, or passing an object whose type mismatches the accessible object's declaring class for instance member checks).
Common situations: Running Gson under a strict JPMS setup without --add-opens to java.base; a SecurityManager that blocks reflective invocation; custom JVMs (GraalVM Native Image, some embedded runtimes) where canAccess behaves unexpectedly; concurrent classloading edge cases.
Related errors
- Cannot allocate {c}. Usage of JDK sun.misc.Unsafe is enabled
- Failed making " + description + " accessible; either increas
- memberDescription + " is not accessible and ReflectionAccess
- Unexpected IllegalAccessException occurred (Gson " + GsonBui
- GSON ({GsonBuildConfig.VERSION}) cannot handle {type}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/10f98fcc595bf3af.json.
Report an issue: GitHub.