pentaho/pentaho-kettle · critical · KettleException
Unable to get document.
Error message
Unable to get document.
What it means
During Wsdl.readWsdl() (invoked from Wsdl.parse()), the WSDL document is fetched over HTTP via HTTPProtocol.get() and parsed with XMLHandler.loadXMLString. If the HTTP fetch succeeds but the returned string does not parse into a Document (doc == null), a KettleException 'Unable to get document.' is thrown because there is nothing to feed to the wsdl4j WSDLReader.
Solutions
- Paste the WSDL URL into a browser or curl to confirm it returns actual XML (<definitions>...), not HTML or an empty body.
- Verify username/password — an HTML-form or 401 challenge page will not parse as a WSDL document.
- Correct the wsdlURI; a mistyped host/path often yields an HTML error page.
- Check proxy/firewall settings so the HTTP request reaches the service host and returns the real WSDL.
Example fix
// before
Wsdl wsdl = new Wsdl(new URI("http://host/services?wsdl"), user, pass, svcQName);
// after — verify the URL returns XML first
// curl -u user:pass http://host/services?wsdl | head → must start with <?xml / <wsdl:definitions>
Wsdl wsdl = new Wsdl(new URI("http://host/services?wsdl"), user, pass, svcQName); Defensive patterns
Strategy: try-catch
Validate before calling
// Check the WSDL URL returns XML before constructing Wsdl
String body = new HTTPProtocol().get(wsdlUrl, user, pass);
if (body == null || body.trim().isEmpty() || !body.contains("<definitions")) {
throw new IllegalStateException("URL did not return a WSDL document: " + wsdlUrl);
} Try / catch
try {
wsdl = new Wsdl(wsdlURI, username, password, serviceQName);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().contains("Unable to get document")) {
logError("WSDL URL returned no parseable XML — check URL, credentials, proxy: " + wsdlURI, e);
}
throw e;
} Prevention
- curl the ?wsdl URL before wiring it into the step
- Watch for HTML login/error pages returned with HTTP 200
- Verify proxy and credentials early
When it happens
Trigger: Calling new Wsdl(wsdlURI, username, password, serviceQName) where the HTTP response body yields null after XML parsing — e.g., an empty body, or the server returning an HTML error/login page that XMLHandler refuses to load as XML.
Common situations: The WSDL URL points to a portal login redirect instead of the raw WSDL; the server returns 200 with an empty body; a proxy or firewall intercepts the request; the URL is mistyped and returns a generic HTML 404 page; credentials are wrong and the server returns an HTML challenge.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Cannot load WSDL file: + _wsdlName
- Carte.Error.NoServerFound
- Client error creating folder
- CmsTokenProvider: Keycloak token request failed — HTTP
- Could not load WSDL file: + e.getMessage()
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/6e63b1dfc0b3c1ad.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/webservices/wsdl/Wsdl.java:373
* @return wsdl Definition
* @throws WSDLException
* on error.
*/
private Definition parse( URI wsdlURI, String username, String password ) throws WSDLException, KettleException,
AuthenticationException {
WSDLReader wsdlReader = getReader();
return readWsdl( wsdlReader, wsdlURI.toString(), username, password );
}
private Definition readWsdl( WSDLReader wsdlReader, String uri, String username, String password ) throws WSDLException, KettleException, AuthenticationException {
try {
HTTPProtocol http = new HTTPProtocol();
Document doc = XMLHandler.loadXMLString( http.get( wsdlURI.toString(), username, password ), true, false );
if ( doc != null ) {
return ( wsdlReader.readWSDL( doc.getBaseURI(), doc ) );
} else {
throw new KettleException( "Unable to get document." );
}
} catch ( MalformedURLException mue ) {
throw new KettleException( mue );
} catch ( AuthenticationException ae ) {
// re-throw this. If not IOException seems to catch it
throw ae;
} catch ( IOException ioe ) {
throw new KettleException( ioe );
}
}
/**
* Returns this objects WSDL types.
*
* @return WsdlTepes
*/
public WsdlTypes getWsdlTypes() {
return this._wsdlTypes;View on GitHub (pinned to f3058517a1)