flowable/flowable-engine · error · FlowableException

Could not deserialize event to xml

Error message

Could not deserialize event to xml

What it means

StringToXmlDocumentDeserializer.deserialize converts the raw event to UTF-8 bytes and parses them with a DocumentBuilder into an org.w3c.dom.Document. Any parse failure (SAXException, IOException, malformed XML) is wrapped in FlowableException 'Could not deserialize event to xml'.

Solutions

  1. Log rawEvent (convertEventToBytes output as UTF-8) and validate it with an XML parser to locate the syntax error.
  2. Ensure the inbound channel deserializer matches the producer's format (XML producer for StringToXmlDocumentDeserializer).
  3. Check for truncation/encoding issues (UTF-8 expected, watch for BOMs and misdeclared encodings).
  4. If rawEvent is not already XML, serialize it properly to an XML string before passing it in.

Example fix

// before
deserializer.deserialize(jsonBody); // throws

// after
deserializer.deserialize("<order><id>1</id></order>");
Defensive patterns

Strategy: validation

Validate before calling

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
try {
    dbf.newDocumentBuilder().parse(new InputSource(new StringReader(rawEvent.toString())));
} catch (Exception e) {
    throw new IllegalArgumentException("Raw event is not well-formed XML: " + e.getMessage());
}
// safe to call deserializer.deserialize(rawEvent)

Type guard

boolean isValidXml(Object rawEvent) {
    try {
        DocumentBuilderFactory.newInstance().newDocumentBuilder()
            .parse(new InputSource(new StringReader(rawEvent.toString())));
        return true;
    } catch (Exception e) {
        return false;
    }
}

Try / catch

try {
    Document doc = deserializer.deserialize(rawEvent);
} catch (FlowableException e) {
    logger.error("Event is not well-formed XML: {}", rawEvent);
    // route to dead-letter / error channel
}

Prevention

When it happens

Trigger: deserialize(rawEvent) invoked with content that is not well-formed XML — e.g. a JSON body on an XML channel, an empty or truncated document, undeclared entity references, or an object whose toString() is not XML.

Common situations: JSON producer feeding an XML-configured channel; messages truncated by transport limits; XML with undeclared namespaces/entities or BOM/encoding mismatches; using non-string objects as raw events.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/4a16032b2d83ba4a. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/serialization/StringToXmlDocumentDeserializer.java:52

            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            
            documentBuilderFactory.setValidating(false);
            documentBuilderFactory.setExpandEntityReferences(false);
            documentBuilderFactory.setXIncludeAware(false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            
            
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            try (InputStream inputStream = new ByteArrayInputStream(convertEventToBytes(rawEvent))) {
                Document document = documentBuilder.parse(inputStream);
                return document;
            }
            
        } catch (Exception e) {
            throw new FlowableException("Could not deserialize event to xml", e);
        }
    }

    public byte[] convertEventToBytes(Object rawEvent) {
        return rawEvent.toString().getBytes(StandardCharsets.UTF_8);
    }
    
}

View on GitHub (pinned to d6d39ce1c6)