pentaho/pentaho-kettle · error · KettleValueException

: can't be converted to a timestamp

Error message

 : can't be converted to a timestamp

What it means

Thrown by ValueMetaTimestamp.convertData when the source value metadata has a storage type that has no defined conversion to Timestamp. Only Number, Date and BigNumber source types are supported; anything else hits the default branch and a KettleValueException is thrown.

Solutions

  1. Convert String sources to Date first, then to Timestamp
  2. Fix upstream field metadata so the source type is Date/Number/BigNumber
  3. Insert a 'Value Mapper'/'Select Values' metadata change step between the streams

Example fix

// before
Timestamp ts = (Timestamp) tsMeta.convertData(stringMeta, data);
// after
Object asDate = dateMeta.convertData(stringMeta, data);
Timestamp ts = (Timestamp) tsMeta.convertData(dateMeta, asDate);
Defensive patterns

Strategy: type-guard

Validate before calling

if (sourceMeta.getType() != ValueMetaInterface.TYPE_DATE
 && sourceMeta.getType() != ValueMetaInterface.TYPE_NUMBER
 && sourceMeta.getType() != ValueMetaInterface.TYPE_BIGNUMBER) {
  throw new IllegalArgumentException("Cannot convert source type " + sourceMeta.getTypeDesc() + " to Timestamp");
}

Type guard

boolean canConvertToTimestamp(ValueMetaInterface src) {
  int t = src.getType();
  return t == ValueMetaInterface.TYPE_DATE || t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_BIGNUMBER;
}

Try / catch

try {
  return tsMeta.convertData(srcMeta, data);
} catch (KettleValueException e) {
  return tsMeta.convertData(dateMeta, srcMeta.getType() == ValueMetaInterface.TYPE_STRING ? srcMeta.convertToNormalStorageTypes(data) : data);
}

Prevention

When it happens

Trigger: Calling convertData(meta2, data2) where meta2 is a ValueMeta of type String, Boolean, Integer, Binary or Serializable — e.g. converting a String field directly to Timestamp without going through Date.

Common situations: Row conversions in transform steps when field type metadata changed (e.g. field switched from Date to String upstream), mapping steps bridging streams with mismatched types.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaTimestamp.java:438

   * @throws KettleValueException in case there is a data conversion error
   */
  @Override
  public Object convertData( ValueMetaInterface meta2, Object data2 ) throws KettleValueException {
    switch ( meta2.getType() ) {
      case TYPE_TIMESTAMP:
        return ( (ValueMetaTimestamp) meta2 ).getTimestamp( data2 );
      case TYPE_STRING:
        return convertStringToTimestamp( meta2.getString( data2 ) );
      case TYPE_INTEGER:
        return convertIntegerToTimestamp( meta2.getInteger( data2 ) );
      case TYPE_NUMBER:
        return convertNumberToTimestamp( meta2.getNumber( data2 ) );
      case TYPE_DATE:
        return convertDateToTimestamp( meta2.getDate( data2 ) );
      case TYPE_BIGNUMBER:
        return convertBigNumberToTimestamp( meta2.getBigNumber( data2 ) );
      default:
        throw new KettleValueException( meta2.toStringMeta() + " : can't be converted to a timestamp" );
    }
  }

  @Override
  public Object cloneValueData( Object object ) throws KettleValueException {
    Timestamp timestamp = getTimestamp( object );
    if ( timestamp == null ) {
      return null;
    }

    Timestamp clone = new Timestamp( timestamp.getTime() );
    clone.setNanos( timestamp.getNanos() );
    return clone;
  }

  @Override
  public ValueMetaInterface getMetadataPreview( DatabaseMeta databaseMeta, ResultSet rs )
    throws KettleDatabaseException {

View on GitHub (pinned to f3058517a1)