hibernate/hibernate-orm · error · PersistenceException
Unable to obtain input stream from [{}]
Error message
Unable to obtain input stream from [{}] What it means
Thrown by PersistenceXmlParser.loadUrlWithJaxb() as a PersistenceException when URL.openConnection() succeeded but connection.getInputStream() raised an IOException while reading a persistence.xml resource. The resource URL resolved, but the actual stream could not be opened - the connection to the resource broke at read time. The resource name is included in the message.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java:326
}
throw new PersistenceException( "Unknown persistence unit transaction type : " + value );
}
}
private JaxbPersistenceImpl loadUrlWithJaxb(URL xmlUrl) {
final String resourceName = xmlUrl.toExternalForm();
try {
var connection = xmlUrl.openConnection();
// avoid JAR locking on Windows and Tomcat
connection.setUseCaches( false );
try ( var inputStream = connection.getInputStream() ) {
return new ConfigurationBinder( classLoaderService )
.bind( new StreamSource( inputStream ),
new Origin( SourceType.URL, resourceName ) )
.getRoot();
}
catch (IOException e) {
throw new PersistenceException( "Unable to obtain input stream from [" + resourceName + "]", e );
}
}
catch (IOException e) {
throw new PersistenceException( "Unable to access [" + resourceName + "]", e );
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Verify the resource named in the message exists and is readable at bootstrap time (open it manually from the same classloader).
- Rebuild/redeploy the artifact to eliminate a corrupted or truncated jar.
- On Windows/Tomcat, ensure no process locks the jar (setUseCaches(false) is already applied by Hibernate) and stop parallel redeployments during boot.
- If the file lives on a remote URL, check network availability and server logs for the refused read.
Example fix
// before: jar replaced while app boots // after: deploy atomically - build the war fully, then swap it in one step // e.g. cp app.war.new tmp/ && mv tmp/app.war.new webapps/app.war
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-open the descriptor from the same classloader before boot
URL url = Thread.currentThread().getContextClassLoader().getResource("META-INF/persistence.xml");
if (url == null) throw new IllegalStateException("persistence.xml not found");
try (InputStream in = url.openConnection().getInputStream()) { in.read(); } // fail with your own error Try / catch
catch (PersistenceException e) {
if (e.getMessage() != null && e.getMessage().contains("Unable to obtain input stream")) {
log.error("persistence.xml unreadable (locked/removed/corrupt jar): {}", e.getMessage());
}
throw e;
} Prevention
- Deploy archives atomically: build the full artifact, then swap it in one step.
- Keep classpath entries immutable while the application boots; no parallel repackaging.
When it happens
Trigger: Opening the persistence.xml URL during parsing where the jar/file was deleted, swapped, or locked between URL resolution and stream read; a jar entry that reports a size but cannot be read (corrupt zip); permission denied on the file; connection refused for an http-hosted descriptor.
Common situations: Hot redeploy/repackaging on Windows where the old jar is locked or removed mid-boot; exploded deployments whose META-INF/persistence.xml permissions changed; partially uploaded or corrupted jar files; Tomcat/JBoss wars being modified while Hibernate scans them.
Related errors
- Unable to access [{}]
- Could not resolve jar-file: <jarFileReference>
- Unable to extract bytes from InputStream
- Unable to access stream from jar file [%s] for entry [%s]
- Error accessing jar file [<rootFilePath>]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/abf5fe22a1b3d316.
Report an issue: GitHub.