{"record":{"id":"71ac0625d6352f74","repo":"hibernate/hibernate-orm","slug":"unrecognized-jpa-persistence-xml-xsd-version","errorCode":null,"errorMessage":"Unrecognized JPA persistence.xml XSD version : `{}`","messagePattern":"Unrecognized JPA persistence\\.xml XSD version : `(.+?)`","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java","lineNumber":84,"sourceCode":"\t\t\t\treturn getJPA21();\n\t\t\t}\n\t\t\tcase \"2.2\": {\n\t\t\t\treturn getJPA22();\n\t\t\t}\n\t\t\tcase \"3.0\": {\n\t\t\t\treturn getJPA30();\n\t\t\t}\n\t\t\tcase \"3.1\": {\n\t\t\t\treturn getJPA31();\n\t\t\t}\n\t\t\tcase \"3.2\": {\n\t\t\t\treturn getJPA32();\n\t\t\t}\n\t\t\tcase \"4.0\": {\n\t\t\t\treturn getJPA40();\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new IllegalArgumentException( \"Unrecognized JPA persistence.xml XSD version : `\" + version + \"`\" );\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static XsdDescriptor cfgXsd() {\n\t\tfinal int index = 0;\n\t\tsynchronized ( xsdCache ) {\n\t\t\tXsdDescriptor cfgXml = xsdCache[index];\n\t\t\tif ( cfgXml == null ) {\n\t\t\t\tcfgXml = LocalXsdResolver.buildXsdDescriptor(\n\t\t\t\t\t\t\"org/hibernate/xsd/cfg/legacy-configuration-4.0.xsd\",\n\t\t\t\t\t\t\"4.0\" ,\n\t\t\t\t\t\t\"http://www.hibernate.org/xsd/orm/cfg\"\n\t\t\t\t);\n\t\t\t\txsdCache[index] = cfgXml;\n\t\t\t}\n\t\t\treturn cfgXml;\n\t\t}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java#L66-L102","documentation":"ConfigXsdSupport.jpaXsd(String) maps an explicit JPA version string to the cached persistence.xml XsdDescriptor. The switch accepts exactly \"1.0\", \"2.0\", \"2.1\", \"2.2\", \"3.0\", \"3.1\", \"3.2\", \"4.0\"; any other string (typo, padded whitespace, locale decimal like \"2,1\", or a version newer than this Hibernate knows, e.g. \"5.0\") falls into default and throws IllegalArgumentException.","triggerScenarios":"Calling ConfigXsdSupport.jpaXsd(version) (directly or via bootstrap code that resolves a requested persistence.xml XSD version) with a string outside the supported set - for example \"2.1 \", \"3.0.0\", \"JPA 3.1\", or a future version on an older hibernate-core.","commonSituations":"Passing a user-supplied or config-file-derived version string straight into the API without normalizing; upgrading the persistence.xsd version attribute ahead of upgrading Hibernate; regional settings producing comma decimals; integrations hardcoding versions this build does not know.","solutions":["Use one of the supported exact strings: 1.0, 2.0, 2.1, 2.2, 3.0, 3.1, 3.2, 4.0.","Normalize before calling: trim whitespace, strip patch suffixes (\"3.1.0\" -> \"3.1\"), and reject comma decimals early.","If you genuinely need a newer JPA XSD, upgrade hibernate-core to a release whose ConfigXsdSupport knows that version.","Validate external version inputs against a whitelist before they reach Hibernate."],"exampleFix":"// before\nXsdDescriptor xsd = configXsdSupport.jpaXsd( requestedVersion ); // requestedVersion = \"3.1.0\" -> throws\n\n// after\nString v = requestedVersion.trim().replaceAll( \"^(\\\\d+\\\\.\\\\d+).*$\", \"$1\" );\nif ( !Set.of( \"1.0\",\"2.0\",\"2.1\",\"2.2\",\"3.0\",\"3.1\",\"3.2\",\"4.0\" ).contains( v ) ) {\n    throw new IllegalArgumentException( \"Unsupported JPA version: \" + requestedVersion );\n}\nXsdDescriptor xsd = configXsdSupport.jpaXsd( v );","handlingStrategy":"validation","validationCode":"private static final Set<String> SUPPORTED_PERSISTENCE_XML_VERSIONS =\n        Set.of( \"1.0\", \"2.0\", \"2.1\", \"2.2\", \"3.0\", \"3.1\", \"3.2\", \"4.0\" );\n\nstatic String normalizeJpaVersion(String raw) {\n    String v = raw == null ? null : raw.trim().replaceAll( \"^(\\\\d+\\\\.\\\\d+).*$\", \"$1\" );\n    if ( !SUPPORTED_PERSISTENCE_XML_VERSIONS.contains( v ) )\n        throw new IllegalArgumentException( \"Unsupported persistence.xml version: \" + raw );\n    return v;\n}","typeGuard":"static boolean isSupportedJpaPersistenceXmlVersion(String v) {\n    return v != null && Set.of( \"1.0\",\"2.0\",\"2.1\",\"2.2\",\"3.0\",\"3.1\",\"3.2\",\"4.0\" ).contains( v );\n}","tryCatchPattern":"try { return configXsdSupport.jpaXsd( requested ); }\ncatch ( IllegalArgumentException e ) {\n    if ( e.getMessage().startsWith( \"Unrecognized JPA persistence.xml XSD version\" ) ) {\n        return configXsdSupport.jpaXsd( normalizeJpaVersion( requested ) );\n    }\n    throw e;\n}","preventionTips":["Whitelist and normalize version strings from config files before passing them to Hibernate.","Upgrade hibernate-core whenever you adopt a newer JPA persistence.xml version.","Never pass locale-formatted numbers (comma decimals) or patch-suffixed strings ('3.1.0') as version identifiers."],"tags":["hibernate","xsd","persistence-xml","version","validation"],"backgroundTag":"unsupported-xsd-version","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}