pentaho/pentaho-kettle · error · KettleStepException

ERROR0014

ERROR0014

Error message

WebServices.ERROR0014.urlNotSpecified

What it means

Thrown by the WebService (SOAP lookup) step's processRow() when the step's URL is empty or null. The step cannot issue a SOAP request without a target service URL, so it aborts immediately with a KettleStepException naming the step. This is a configuration validation check, not a runtime/network failure.

Solutions

  1. Open the WebService step dialog and set the URL field
  2. If the URL uses a variable, define that variable (e.g. via kettle.properties or Set Variables) before execution
  3. Check the saved transformation file/repo actually contains the URL attribute for the step

Example fix

// before
String url = getVariable( "SERVICE_URL", "" ); // empty -> step fails
// after
String url = getVariable( "SERVICE_URL", "" );
if ( Utils.isEmpty( url ) ) {
  throw new KettleException( "SERVICE_URL variable must be set before running the transformation" );
}
Defensive patterns

Strategy: validation

Validate before calling

// validate meta before running the transformation
WebServiceMeta meta = (WebServiceMeta) stepMeta.getStepMetaInterface();
if ( meta.getUrl() == null || meta.getUrl().trim().isEmpty() ) {
  throw new IllegalArgumentException( "WebService step '" + stepMeta.getName() + "' has no URL configured" );
}

Try / catch

try {
  trans.execute( null );
} catch ( KettleException e ) {
  if ( e.getMessage() != null && e.getMessage().contains( "ERROR0014" ) ) {
    logError( "WebService step missing URL; fix step configuration" );
  }
}

Prevention

When it happens

Trigger: Running a transformation where the WebService step meta has meta.getUrl() returning null/empty — i.e., no URL was entered in the step dialog or loaded from the transformation metadata.

Common situations: Transformation XML/kettle property not carrying the URL field after copy-paste between environments, variable-based URL (${SERVICE_URL}) left undefined, or a newly added step configured only partially.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/webservices/WebService.java:149

  public WebService( StepMeta aStepMeta, StepDataInterface aStepData, int value, TransMeta aTransMeta, Trans aTrans ) {
    super( aStepMeta, aStepData, value, aTransMeta, aTrans );

    // Reference date used to format hours
    try {
      dateRef = timeFormat.parse( "00:00:00" );
    } catch ( ParseException e ) {
      logError( "Unexpected error in WebService constructor: ", e );
      setErrors( 1 );
      stopAll();
    }
  }

  public boolean processRow( StepMetaInterface metaInterface, StepDataInterface dataInterface ) throws KettleException {
    meta = (WebServiceMeta) metaInterface;

    // if a URL is not specified, throw an exception
    if ( Utils.isEmpty( meta.getUrl() ) ) {
      throw new KettleStepException( BaseMessages.getString(
        PKG, "WebServices.ERROR0014.urlNotSpecified", getStepname() ) );
    }

    // if an operation is not specified, throw an exception
    if ( Utils.isEmpty( meta.getOperationName() ) ) {
      throw new KettleStepException( BaseMessages.getString(
        PKG, "WebServices.ERROR0015.OperationNotSelected", getStepname() ) );
    }

    data = (WebServiceData) dataInterface;
    Object[] vCurrentRow = getRow();

    if ( first ) {
      first = false;

      if ( getInputRowMeta() != null ) {
        data.outputRowMeta = getInputRowMeta().clone();
      } else {

View on GitHub (pinned to f3058517a1)