{"record":{"id":"865395867b452375","repo":"pentaho/pentaho-kettle","slug":"rest-error-cannotreadurl","errorCode":"Rest.Error.CanNotReadURL","errorMessage":"Rest.Error.CanNotReadURL","messagePattern":"Rest\\.Error\\.CanNotReadURL","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/rest/core/src/main/java/org/pentaho/di/trans/steps/rest/Rest.java","lineNumber":83,"sourceCode":" */\npublic class Rest extends BaseStep implements StepInterface {\n  private static Class<?> PKG = RestMeta.class; // for i18n purposes, needed by Translator2!!\n\n  private static final String HEADER_CONTENT_TYPE = \"Content-Type\";\n\n  private RestMeta meta;\n  private RestData data;\n\n  public Rest( StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta, Trans trans ) {\n    super( stepMeta, stepDataInterface, copyNr, transMeta, trans );\n  }\n\n  protected Object[] callRest( Object[] rowData ) throws KettleException {\n    try ( Client client = getClient( rowData ) ) {\n      WebTarget target = buildRequest( client, rowData );\n      return invokeRequest( target, rowData );\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Rest.Error.CanNotReadURL\", data.realUrl ), e );\n    }\n  }\n\n  protected Client getClient( Object[] rowData ) throws KettleException {\n    // get dynamic url ?\n    if ( meta.isUrlInField() ) {\n      data.realUrl = data.inputRowMeta.getString( rowData, data.indexOfUrlField );\n    }\n\n    // get dynamic method?\n    if ( meta.isDynamicMethod() ) {\n      data.method = data.inputRowMeta.getString( rowData, data.indexOfMethod );\n      if ( Utils.isEmpty( data.method ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"Rest.Error.MethodMissing\" ) );\n      }\n    }\n\n    if ( isDetailed() ) {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/rest/core/src/main/java/org/pentaho/di/trans/steps/rest/Rest.java#L65-L101","documentation":"Rest.callRest wraps the whole REST invocation (client creation, request build, execution) and converts any exception into a KettleException with the localized message Rest.Error.CanNotReadURL, including the resolved URL (data.realUrl). It is the generic 'the REST call did not succeed' boundary for this Pentaho Kettle step.","triggerScenarios":"Any failure inside callRest: malformed URL, unknown host, connection refused, invalid method field, SSL errors, or a runtime failure while building/executing the request against data.realUrl.","commonSituations":"Typo or missing protocol in the URL field; DNS failure in an air-gapped environment; target service down; URL taken from an input field containing bad data at runtime.","solutions":["Read the chained cause exception (getCause()) to find the real failure (UnknownHostException, ConnectException, SSLHandshakeException, etc.)","Verify the URL configured in the step (or in the URL input field for the current row) is correct and reachable (curl it)","Check hostname resolution and firewall/proxy settings on the machine running the transformation","If the URL comes from a field, preview the row data to confirm the value is a valid URL","Test SSL configuration (trust store, 'ignore SSL' option) if the cause is a handshake failure"],"exampleFix":"// before\ndata.realUrl = urlInField ? row[urlFieldIdx] : meta.getUrl();\n// after\nString candidate = urlInField ? row[urlFieldIdx] : meta.getUrl();\nif ( candidate == null || !candidate.matches( \"^https?://.+\" ) ) {\n  throw new KettleException( \"Invalid REST URL: \" + candidate );\n}\ndata.realUrl = candidate;","handlingStrategy":"try-catch","validationCode":"String url = meta.isUrlInField() ? (String) rowData[data.indexOfUrlField] : environmentSubstitute( meta.getUrl() );\nif ( url == null || !url.matches( \"^https?://[^\\s]+$\" ) ) {\n  throw new KettleException( \"Invalid REST URL: \" + url );\n}","typeGuard":null,"tryCatchPattern":"try {\n  Object[] out = step.callRest( row );\n} catch ( KettleException e ) {\n  Throwable cause = e.getCause();\n  if ( cause instanceof java.net.UnknownHostException ) { /* fix DNS */ }\n  else if ( cause instanceof javax.net.ssl.SSLException ) { /* fix trust store */ }\n  else if ( cause instanceof java.net.ConnectException ) { /* service down */ }\n  log.error( \"REST call to \" + realUrl + \" failed\", e );\n}","preventionTips":["Preview row data when URL-in-field is enabled to catch bad values before run time","Always read the cause chain — CanNotReadURL is only a wrapper","Validate URL fields with a regex or a Filter step upstream","Test connectivity (curl/telnet) from the machine running the transformation"],"tags":["http","kettle","network"],"backgroundTag":"http-request-failed","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"}