{"record":{"id":"58caa773610111af","repo":"pentaho/pentaho-kettle","slug":"carte-error-noshutdown","errorCode":"Carte.Error.NoShutdown","errorMessage":"Carte.Error.NoShutdown","messagePattern":"Carte\\.Error\\.NoShutdown","errorType":"exception","errorClass":"Carte.CarteCommandException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/Carte.java","lineNumber":377,"sourceCode":"      }\n\n      client.register( HttpAuthenticationFeature.basic( username, Encr.decryptPasswordOptionallyEncrypted( password ) ) );\n\n      // check if the user can access the carte server. Don't really need this call but may want to check it's output at\n      // some point\n      String contextURL = HttpUtil.constructUrl( new Variables(), hostname, port, \"kettle\", \"\", sslMode );\n      WebTarget target = client.target( contextURL + \"/status/?xml=Y\" );\n      String response = target.request().get( String.class );\n      if ( response == null || !response.contains( \"<serverstatus>\" ) ) {\n        throw new Carte.CarteCommandException( BaseMessages.getString( PKG, NO_SERVER_FOUND_ERROR, hostname, \"\"\n            + port ) );\n      }\n\n      // This is the call that matters\n      target = client.target( contextURL + \"/stopCarte\" );\n      response = target.request().get( String.class );\n      if ( response == null || !response.contains( \"Shutting Down\" ) ) {\n        throw new Carte.CarteCommandException( BaseMessages.getString( PKG, \"Carte.Error.NoShutdown\", hostname, \"\"\n            + port ) );\n      }\n    } catch ( Exception e ) {\n      throw new Carte.CarteCommandException( BaseMessages.getString( PKG, NO_SERVER_FOUND_ERROR, hostname, \"\"\n          + port ), e );\n    }\n  }\n\n  private static Client createClientWithSSLConfig( SslConfiguration sslConfig, String hostname, String port  )\n    throws CarteCommandException {\n    HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();\n    SSLContext sslContext;\n    try {\n      sslContext = getSSLContext( sslConfig.getKeyStore(), sslConfig.getKeyStorePassword() );\n    } catch ( Exception e ) {\n      CarteSingleton.getInstance().getLog().logError( \"Unable to create SSL context. Please check SSL configuration.\" );\n      throw new Carte.CarteCommandException( BaseMessages.getString( PKG, NO_SERVER_FOUND_ERROR, hostname, \"\" + port ), e );\n    }","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/Carte.java#L359-L395","documentation":"CarteCommandException thrown by callStopCarteRestService when the REST response from the remote Carte server's /stopCarte endpoint is null or does not contain 'Shutting Down'. It means the server was contacted (or not) but did not confirm shutdown. The library throws it to signal that the remote Carte instance could not be verified as stopping.","triggerScenarios":"Carte.shutdown() -> callStopCarteRestService() performs GET {contextURL}/stopCarte; the response body is null, empty, or lacks the 'Shutting Down' confirmation string (e.g. wrong port, already stopped, auth or proxy interfering, non-Carte service on that port).","commonSituations":"Pointing at the wrong Carte hostname/port; Carte already shut down so /stopCarte returns an error page; a firewall/proxy strips or rewrites the response; the Carte version on the remote host returns a different confirmation text.","solutions":["Verify the Carte server is running and reachable at the given hostname:port before calling shutdown","Check the /stopCarte endpoint manually (curl http://host:port/stopCarte) to see the actual response","Confirm no proxy, firewall, or servlet filter is altering the response body","Check remote Carte logs for errors during shutdown handling","Ensure the remote Carte version returns the standard 'Shutting Down' confirmation"],"exampleFix":"// before\nresponse = target.request().get( String.class );\nif ( response == null || !response.contains( \"Shutting Down\" ) ) {\n  throw new CarteCommandException(...);\n}\n// after\nresponse = target.request().get( String.class );\nif ( response == null || !(response.contains( \"Shutting Down\" ) || response.contains( \"shutting down\" )) ) {\n  // retry once before failing, then log the raw body for diagnosis\n  LOG.warn(\"Unexpected /stopCarte response: \" + response);\n  throw new CarteCommandException(...);\n}","handlingStrategy":"try-catch","validationCode":"// Before shutdown, ping the server\nHttpGet ping = new HttpGet( \"http://\" + hostname + \":\" + port + \"/kettle/status/\" );\n// expect HTTP 200; if not reachable, skip shutdown call","typeGuard":"boolean isShutdownConfirmation( String response ) {\n  return response != null && response.contains( \"Shutting Down\" );\n}","tryCatchPattern":"try {\n  carte.shutdown( hostname, port );\n} catch ( Carte.CarteCommandException e ) {\n  // distinguish: response received but no confirmation vs network error\n  LOG.warn( \"Carte at \" + hostname + \":\" + port + \" did not confirm shutdown: \" + e.getMessage() );\n}","preventionTips":["Health-check the Carte server before calling shutdown","Pin/verify Carte versions so confirmation text is stable","Avoid proxies between client and Carte for management calls","Log raw /stopCarte responses during troubleshooting"],"tags":["carte","rest","shutdown","http"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}