pentaho/pentaho-kettle · error · KettleException

JobTrans.Exception.MetaDataLoad

Error message

JobTrans.Exception.MetaDataLoad

What it means

This is the catch-all wrapper at the end of getMetaForEntry: any non-KettleException thrown while resolving, loading, caching, or variable-reseeding the referenced meta (TransMeta/JobMeta) is wrapped in a KettleException whose message is the localized 'JobTrans.Exception.MetaDataLoad' (metadata load failure). The original exception is preserved as the cause. It signals that loading the child transformation/job metadata failed for an unexpected reason — I/O errors, parsing failures, repository errors, NPEs, etc.

Solutions

  1. Inspect the wrapped cause (KettleException.getCause()) — it names the real failure (file not found, parse error, repo error).
  2. Verify the referenced file path / repository object still exists and is readable; re-select the reference in Spoon and re-save the job.
  3. Validate the ktr/kjb XML opens cleanly in Spoon; fix or regenerate corrupted metadata.
  4. Ensure required VFS/connection plugins are installed and the process has filesystem permissions for the referenced path.
  5. Wrap the call site in try/catch (KettleException ke) and log ke.getCause() for diagnostics before retrying or failing the parent job.

Example fix

// before
theMeta = jobEntryLoader.getMetaForEntry( bowl, rep, metaStore, space ); // opaque MetaDataLoad failure

// after
try {
  theMeta = jobEntryLoader.getMetaForEntry( bowl, rep, metaStore, space );
} catch ( KettleException ke ) {
  logError( "Loading job entry metadata failed: " + ke.getMessage(), ke.getCause() );
  throw ke;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check the referenced artifact exists and is readable before loading
String path = jobEntry.getFilename();
if ( path != null && !new File( path ).canRead() ) {
  throw new FileNotFoundException( "Referenced metadata not readable: " + path );
}

Type guard

boolean metaLoadable( Repository rep, JobEntryInterface e, VariableSpace space ) {
  switch ( e.getSpecificationMethod() ) {
    case FILENAME: return e.getFilename() != null && new File( space.environmentSubstitute( e.getFilename() ) ).canRead();
    case REPOSITORY_BY_REFERENCE: return rep != null && e.getObjectId() != null;
    case REPOSITORY_BY_NAME: return rep != null && e.getName() != null;
    default: return false;
  }
}

Try / catch

try {
  meta = loader.getMetaForEntry( bowl, rep, metaStore, space );
} catch ( KettleException ke ) {
  Throwable cause = ke.getCause();
  logError( "Metadata load failed: " + ke.getMessage() + " caused by " + cause, cause );
  if ( cause instanceof FileNotFoundException || cause instanceof IOException ) {
    throw new JobExecutionException( "Referenced transformation/job file missing or unreadable", ke );
  }
  throw ke;
}

Prevention

When it happens

Trigger: Any unexpected Exception inside getMetaForEntry: unreadable or malformed ktr/kjb file in FILENAME mode, repository load throwing a non-Kettle RuntimeException, errors in attemptLoadMeta/getMetaFromRepository, ClassCastException, or failures in reseedInternalDirectoryVars/cacheMeta.

Common situations: Referenced transformation file deleted or moved after the job was authored; corrupt or partially written ktr/kjb XML; missing VFS plugins (pvfs/hdfs) so file resolution throws; permission errors reading the file; repository connectivity flakiness surfacing as a raw exception.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java:284

          }
          break;
        default:
          throw new KettleException( "The specified object location specification method '"
            + specificationMethod + "' is not yet supported in this " + friendlyMetaType + " entry." );
      }

      cacheMeta( idContainer[ 0 ], theMeta );
      // Re-seed the internal directory variables on the returned meta from the freshly resolved tmpSpace.
      // The cache may return an instance whose internal vars were last set in a different context
      // (e.g. from a step loader using getVarSpaceOnlyWithRequiredParentVars, or with rep==null),
      // which would otherwise leak the wrong Internal.Entry.Current.Directory into the child execution.
      reseedInternalDirectoryVars( theMeta, tmpSpace );
      return theMeta;
    } catch ( final KettleException ke ) {
      // if we get a KettleException, simply re-throw it
      throw ke;
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( persistentClass, "JobTrans.Exception.MetaDataLoad" ), e );
    }
  }

  /**
   * Force the four internal directory variables on the loaded meta to the values resolved by
   * {@link CurrentDirectoryResolver} for *this* job-entry invocation. Without this, a cached
   * TransMeta/JobMeta returned from a previous load can carry stale Internal.Entry.Current.Directory
   * (and friends) inherited from whatever space was active during that earlier load.
   */
  private void reseedInternalDirectoryVars( T theMeta, VariableSpace tmpSpace ) {
    if ( theMeta == null || tmpSpace == null || !( theMeta instanceof org.pentaho.di.base.AbstractMeta ) ) {
      return;
    }
    org.pentaho.di.base.AbstractMeta meta = (org.pentaho.di.base.AbstractMeta) theMeta;
    String entryDir = tmpSpace.getVariable( INTERNAL_VARIABLE_ENTRY_CURRENT_DIRECTORY );
    if ( entryDir != null ) {
      meta.setVariable( INTERNAL_VARIABLE_ENTRY_CURRENT_DIRECTORY, entryDir );
    }

View on GitHub (pinned to f3058517a1)