pentaho/pentaho-kettle · error · ServletException

GetJobStatusServlet.Error.UnableToGetJobStatusInXML

GetJobStatusServlet.Error.UnableToGetJobStatusInXML

Error message

GetJobStatusServlet.Error.UnableToGetJobStatusInXML

What it means

Thrown by GetJobStatusServlet.doGet when generating the XML job-status document fails with a KettleException. The servlet catches the KettleException, sets HTTP 500, and rethrows as a ServletException with this generic message; the real cause is attached.

Solutions

  1. Inspect the wrapped KettleException cause in the server log for the real failure (getLogText OOM, XML generation, etc.).
  2. If caused by log size OOM, reduce the requested log range (use /kettle/jobStatus/ without xml or tail lines) or increase heap / trim KettleLogStore buffer size.
  3. Retry the status request once the job reaches a stable state (finished/stopped); avoid polling during rapid start/stop cycles.
  4. Clear/disable the servlet status cache (useXML with cache bypass parameters) if a stale cached entry is implicated.

Example fix

// before (client)
String xml = httpGet("/kettle/jobStatus/?name=myjob&xml=Y");
// after
try {
  String xml = httpGet("/kettle/jobStatus/?name=myjob&xml=Y");
} catch (HttpServerErrorException e) {
  // HTTP 500: inspect server log for wrapped KettleException cause, retry after job stabilizes
  retryWithBackoff("/kettle/jobStatus/?name=myjob&xml=Y");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client: only request XML once the job reports a stable state
String state = httpGet("/kettle/jobStatus/?name=" + jobName); // non-XML poll first
boolean safeToPollXml = state.contains("Finished") || state.contains("Stopped") || state.contains("Running");

Try / catch

try {
  String xml = httpGet("/kettle/jobStatus/?name=" + jobName + "&xml=Y");
} catch (HttpServerErrorException e) { // 500 with this message
  log.warn("jobStatus XML failed; inspect server log cause", e);
  retryWithBackoff(() -> httpGet("/kettle/jobStatus/?name=" + jobName + "&xml=Y"), 3);
}

Prevention

When it happens

Trigger: GET /kettle/jobStatus/?name=<job>&xml=Y when building the status XML fails — e.g. the JobExecutionConfiguration/status XML generation throws, the log buffer cannot be read, or the job's internal state is inconsistent while serializing.

Common situations: Monitoring clients polling job status in XML mode hit HTTP 500 while a job is stopping/finished; log store issues or corrupt job metadata during XML serialization; cache-enabled polling after a job was removed mid-request.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/409165fcd72236be. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/www/GetJobStatusServlet.java:313

            //
            jobStatus.setResult( job.getResult() ); // might be null


            String xml = jobStatus.getXML();
            data = xml.getBytes( Charset.forName( Const.XML_ENCODING ) );
            out = response.getOutputStream();
            response.setContentLength( XML_HEADER.length + data.length );
            out.write( XML_HEADER );
            out.write( data );
            out.flush();
            if ( finishedOrStopped && ( jobStatus.isFinished() || jobStatus.isStopped() ) && logId != null ) {
              cache.put( logId, xml, startLineNr );
            }
          }
          response.flushBuffer();
        } catch ( KettleException e ) {
          response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
          throw new ServletException( BaseMessages.getString( PKG, "GetJobStatusServlet.Error.UnableToGetJobStatusInXML" ), e );
        }
      } else {

        PrintWriter out = response.getWriter();

        int lastLineNr = KettleLogStore.getLastBufferLineNr();
        int tableBorder = 0;

        response.setContentType( "text/html" );

        out.println( "<HTML>" );
        out.println( "<HEAD>" );
        out
          .println( "<TITLE>"
            + BaseMessages.getString( PKG, "GetJobStatusServlet.KettleJobStatus" ) + "</TITLE>" );
        if ( EnvUtil.getSystemProperty( Const.KETTLE_CARTE_REFRESH_STATUS, "N" ).equalsIgnoreCase( "Y" ) ) {
          out.println( "<META http-equiv=\"Refresh\" content=\"10;url="
            + convertContextPath( GetJobStatusServlet.CONTEXT_PATH ) + "?name="

View on GitHub (pinned to f3058517a1)