jwtk/jjwt · error · IllegalStateException
Unable to read field
Error message
Unable to read field ${instanceClassName}#${fieldName}: ${causeMessage} What it means
IllegalStateException thrown by io.jsonwebtoken.lang.Classes.getFieldValue when reflectively reading a declared field fails — field not found, setAccessible rejected, wrong fieldType cast, or instance/class mismatch. The message embeds the underlying cause message.
Solutions
- Verify the field name and type against the exact jar version on the classpath
- Use the library's public API instead of reading internal fields
- For JDK 9+, add --add-opens / module opens if access is intentional and unavoidable
- Match fieldType to the field's declared type to avoid the cast failure
Example fix
// before String alg = Classes.getFieldValue(header, "algx", String.class); // wrong field name // after String alg = Classes.getFieldValue(header, "alg", String.class);
Defensive patterns
Strategy: try-catch
Validate before calling
try {
java.lang.reflect.Field f = instance.getClass().getDeclaredField(fieldName);
if (!fieldType.isAssignableFrom(f.getType())) {
throw new IllegalArgumentException("Field " + fieldName + " is not " + fieldType);
}
} catch (NoSuchFieldException e) {
throw new IllegalArgumentException("No field " + fieldName + " on " + instance.getClass());
} Try / catch
try {
return Classes.getFieldValue(instance, fieldName, fieldType);
} catch (IllegalStateException e) {
LOG.warn("Reflective field read failed for {}.#{}, cause: {}", instance.getClass(), fieldName, e.getCause());
return defaultValue;
} Prevention
- Avoid reading library internals; use public APIs and accessors
- Pin to a specific jjwt version since internal field names can change
- On JDK 9+, add explicit --add-opens if reflective access is unavoidable
When it happens
Trigger: getFieldValue(instance, fieldName, fieldType) where fieldName does not exist on instance's class, a SecurityManager/module system blocks setAccessible, or field.get returns an object not castable to fieldType.
Common situations: Poking at library internals whose field names changed between jjwt versions; JDK 9+ strong encapsulation denying access to private fields of non-exported packages; wrong expected type parameter causing ClassCastException.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Class method parameter cannot be null.
- Reflection operation failed. This is likely due to an…
- Unable to instantiate class
- Unable to instantiate instance with constructor
- Unable to invoke class method
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/193803b1a9efd20d.
Report an issue: GitHub.
Appendix: source
Thrown at api/src/main/java/io/jsonwebtoken/lang/Classes.java:352
* Returns the {@code instance}'s named (declared) field value.
*
* @param instance the instance with the internal field
* @param fieldName the name of the field to inspect
* @param fieldType the type of field to inspect
* @param <T> field instance value type
* @return the field value
*/
public static <T> T getFieldValue(Object instance, String fieldName, Class<T> fieldType) {
if (instance == null) return null;
try {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object o = field.get(instance);
return fieldType.cast(o);
} catch (Throwable t) {
String msg = "Unable to read field " + instance.getClass().getName() +
"#" + fieldName + ": " + t.getMessage();
throw new IllegalStateException(msg, t);
}
}
/**
* @since 1.0
*/
private interface ClassLoaderAccessor {
Class<?> loadClass(String fqcn);
URL getResource(String name);
InputStream getResourceStream(String name);
}
/**
* @since 1.0
*/
private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor {View on GitHub (pinned to fb71496164)