FasterXML/jackson-databind · error · UnresolvedForwardReference
Could not resolve Object Id [{}] (for {}).
Error message
Could not resolve Object Id [{}] (for {}). What it means
Thrown as an UnresolvedForwardReference by BeanDeserializerBase.deserializeFromObjectId when an object identity reference is encountered (via @JsonIdentityInfo) but the referenced object has not yet been resolved. This means the id was registered with a ReadableObjectId but resolve() returned null — the object was never fully deserialized. Unlike a simple missing id, this specifically creates an UnresolvedForwardReference with location info so it can potentially be resolved later.
Source
Thrown at src/main/java/tools/jackson/databind/deser/bean/BeanDeserializerBase.java:1653
protected Object deserializeWithObjectId(JsonParser p, DeserializationContext ctxt)
throws JacksonException
{
return deserializeFromObject(p, ctxt);
}
/**
* Method called in cases where it looks like we got an Object Id
* to parse and use as a reference.
*/
protected Object deserializeFromObjectId(JsonParser p, DeserializationContext ctxt)
throws JacksonException
{
Object id = _objectIdReader.readObjectReference(p, ctxt);
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
// do we have it resolved?
Object pojo = roid.resolve();
if (pojo == null) { // not yet; should wait...
throw new UnresolvedForwardReference(p,
"Could not resolve Object Id ["+id+"] (for "+_beanType+").",
p.currentLocation(), roid);
}
return pojo;
}
protected Object deserializeFromObjectUsingNonDefault(JsonParser p,
DeserializationContext ctxt)
throws JacksonException
{
// 02-Jul-2024, tatu: [databind#4602] Need to tweak regular and "array" delegating
// Creator handling
final ValueDeserializer<Object> delegateDeser = _delegateDeserializer(p);
if (delegateDeser != null) {
// [databind#5909]: signal delegate-bind-pending so that any ROID
// bound during delegate deserialization retains resolved Referrings
// — needed for collection-property forward refs to be rebound after
// updateObjectId(delegate, bean) below.View on GitHub (pinned to a50c7d2a1d)
Solutions
- Ensure the JSON fully contains all referenced objects — no truncation or missing entries.
- Check @JsonIdentityInfo scope matches between serialization and deserialization (scope must be the same class or a common base).
- If dealing with forward references, handle UnresolvedForwardReference by calling resolveId on the DeserializationContext after the full document is parsed.
- Verify the id generator type (ObjectIdGenerators) is consistent between serialization and deserialization configurations.
Example fix
// before: JSON references id 2 before it appears
{"ref":2}
// after: include the referenced object
{"@id":2,"name":"x","ref":2} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate that the JSON stream contains all referenced ids
JsonNode tree = mapper.readTree(json);
Set<Object> definedIds = extractIds(tree);
Set<Object> referencedIds = extractRefs(tree);
if (!definedIds.containsAll(referencedIds)) {
referencedIds.removeAll(definedIds);
throw new IllegalStateException("Missing object ids: " + referencedIds);
} Try / catch
try {
return mapper.readValue(json, MyClass.class);
} catch (UnresolvedForwardReference e) {
// Optionally: attempt to resolve from a secondary source, or report gracefully
logger.error("Unresolved object id '{}' at {}", e.getUnresolvedId(), e.getLocation());
throw e;
} Prevention
- Ensure JSON graphs are complete — all referenced objects must be defined.
- Verify @JsonIdentityInfo scope is consistent between producer and consumer.
- For forward references, use two-pass parsing: parse, then resolve pending refs.
When it happens
Trigger: JSON with @JsonIdentityInfo where an object id is referenced before it is defined (true forward reference) and the stream ends without the referenced object appearing. Circular references that are not properly handled. An id generator that produces ids not matching the references.
Common situations: Serializing a graph with bidirectional relationships using @JsonIdentityInfo where the deserialization order does not match. Missing or incomplete JSON (truncated stream). Using PROPERTY-based id generation where the id property is absent or mismatched. Polymorphic type processing interfering with identity resolution.
Related errors
- Trying to resolve a forward reference with id [{}] that wasn
- Trying to resolve a forward reference with id [{}] that wasn
- Trying to resolve a forward reference with id [{}] that wasn
- Trying to resolve a forward reference with id [${id}] that w
- Could not resolve Object Id [{}] -- unresolved forward-refer
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/a17735df6b965dd5.
Report an issue: GitHub.