pentaho/pentaho-kettle · error · KettleValueException
: I don't know how to convert binary values to numbers.
Error message
: I don't know how to convert binary values to numbers.
What it means
ValueMetaBase.getNumber() throws this KettleValueException when the value metadata has type TYPE_BINARY, because there is no defined conversion from a raw byte[] payload to a Double number. Pentaho Kettle (PDI) simply refuses to guess a numeric interpretation of opaque binary data. You must decode the bytes yourself (e.g. to a String or numeric type) before requesting a Number.
Solutions
- Change the field's value metadata type from TYPE_BINARY to a convertible type (TYPE_STRING or TYPE_INTEGER) using a 'Select values' / Metadata step or a new ValueMeta before calling getNumber().
- Convert the byte[] manually first (e.g. new ValueMetaString(...).convertBinaryStringToNativeType(bytes) or decode to a String/Integer) and then request the Number.
- If the column is genuinely opaque binary, do not call getNumber(); store/pass it as byte[] and only derive numeric values (length, checksum) explicitly.
- Catch KettleValueException and log/skip the field if binary data in a numeric context is acceptable.
Example fix
// before
ValueMetaInterface meta = new ValueMetaBase("blob", ValueMetaInterface.TYPE_BINARY);
Double n = meta.getNumber(rowData[0]); // throws
// after
ValueMetaInterface meta = new ValueMetaBase("blob", ValueMetaInterface.TYPE_STRING);
Double n = meta.getNumber(meta.convertBinaryStringToNativeType((byte[]) rowData[0])); Defensive patterns
Strategy: type-guard
Validate before calling
if (meta.getType() == ValueMetaInterface.TYPE_BINARY) {
throw new IllegalArgumentException("Field '" + meta.getName() + "' is BINARY; convert to String/Integer before getNumber()");
} Type guard
boolean isNumberConvertible(ValueMetaInterface m) {
int t = m.getType();
return t == ValueMetaInterface.TYPE_STRING || t == ValueMetaInterface.TYPE_INTEGER
|| t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_BIGNUMBER
|| t == ValueMetaInterface.TYPE_BOOLEAN || t == ValueMetaInterface.TYPE_DATE;
} Try / catch
try {
Double n = meta.getNumber(value);
} catch (KettleValueException e) {
log.warn("Cannot convert " + meta.getName() + " (binary) to Number", e);
} Prevention
- Set binary columns (BLOBs, images) to TYPE_STRING or the correct numeric type in input step metadata, never TYPE_BINARY, when numeric use is expected.
- Check meta.getType() before calling any getXxx() conversion helper.
- Centralize conversions behind a utility that maps unsupported types explicitly.
When it happens
Trigger: Calling ValueMeta.getNumber(Object) (or row.getNumber()/getRow with conversion) on a field whose valueMeta.getType() == ValueMetaInterface.TYPE_BINARY and whose data is a byte[].
Common situations: Reading binary columns from databases or files (BLOB, images, PDFs) and asking for them as numbers; misconfigured CSV/text input steps that set the field type to Binary instead of String/Number; custom transformation code that copies row data into Number-typed targets without changing the metadata type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- : I don't know how to convert binary values to BigDecimals.
- : I don't know how to convert serializable values to…
- : I don't know how to convert serializable values to…
- Unexpected conversion error while converting value [" +…
- : can't be converted to an Internet Address
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/9545a24cf0ab6618.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:2041
return new Double( ( (BigDecimal) convertBinaryStringToNativeType( (byte[]) object ) ).doubleValue() );
case STORAGE_TYPE_INDEXED:
return new Double( ( (BigDecimal) index[( (Integer) object ).intValue()] ).doubleValue() );
default:
throw new KettleValueException( toString() + " : Unknown storage type " + storageType + " specified." );
}
case TYPE_BOOLEAN:
switch ( storageType ) {
case STORAGE_TYPE_NORMAL:
return convertBooleanToNumber( (Boolean) object );
case STORAGE_TYPE_BINARY_STRING:
return convertBooleanToNumber( (Boolean) convertBinaryStringToNativeType( (byte[]) object ) );
case STORAGE_TYPE_INDEXED:
return convertBooleanToNumber( (Boolean) index[( (Integer) object ).intValue()] );
default:
throw new KettleValueException( toString() + " : Unknown storage type " + storageType + " specified." );
}
case TYPE_BINARY:
throw new KettleValueException( toString() + " : I don't know how to convert binary values to numbers." );
case TYPE_SERIALIZABLE:
throw new KettleValueException( toString() + " : I don't know how to convert serializable values to numbers." );
default:
throw new KettleValueException( toString() + " : Unknown type " + type + " specified." );
}
} catch ( Exception e ) {
throw new KettleValueException( "Unexpected conversion error while converting value [" + toString()
+ "] to a Number", e );
}
}
@Override
public Long getInteger( Object object ) throws KettleValueException {
try {
if ( isNull( object ) ) {
return null;
}
switch ( type ) {View on GitHub (pinned to f3058517a1)