hibernate/hibernate-orm · error · IllegalArgumentException

XML not properly formed:

Error message

XML not properly formed: 

What it means

Tail of XmlHelper's generic fromString parser: the scan loop reached the end of the string while still inside an element, meaning the closing tag was never found. The stored XML aggregate content is truncated or unterminated.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlHelper.java:425

					}
					break;
				case '/':
					if ( tagName == null ) {
						// A shorthand tag encodes null
						values.add( null );
						// skip the closing angle bracket
						i++;
						tagNameStart = -1;
						assert string.charAt( i ) == '>';
					}
					else {
						// This must be a char in the content
						assert contentStart != -1;
					}
					break;
			}
		}
		throw new IllegalArgumentException( "XML not properly formed: " + string.substring( start ) );
	}

	private static int fromString(
			EmbeddableMappingType embeddableMappingType,
			String string,
			boolean returnEmbeddable,
			WrapperOptions options,
			Object[] values,
			int start) throws SQLException {
		int tagNameStart = -1;
		int contentStart = -1;
		String tagName = null;
		for ( int i = start; i < string.length(); i++ ) {
			final char c = string.charAt( i );
			switch ( c ) {
				case '<':
					if ( tagNameStart == -1 ) {
						if ( string.charAt( i + 1 ) == '/' ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Identify affected rows with a SQL audit (content not ending in the expected closing tag).
  2. Repair or null the truncated rows, then re-write them through Hibernate.
  3. Enlarge the column type (e.g. CLOB/XML type) so writes never truncate again.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return session.find(Person.class, id);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage() != null && ex.getMessage().startsWith("XML not properly formed")) {
        // truncated row: log PK and raw column value for repair
        logTruncated(id, ex.getMessage());
        return null;
    }
    throw ex;
}

Prevention

When it happens

Trigger: Reading an XML aggregate whose content ends before the closing tag: column truncation (VARCHAR too short), partial writes after a crash, or manual edits that removed tags.

Common situations: Column length changed or too small for large aggregates; non-atomic updates by scripts; data truncation during ETL between databases.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/ad2e33fbb088c682. Report an issue: GitHub.