pentaho/pentaho-kettle · error · KettleException
PGBulkLoader doesn't handle the type
Error message
PGBulkLoader doesn't handle the type
What it means
writeRowToPostgres only handles a fixed set of ValueMetaInterface types (String, Number, Integer, BigNumber, Date, Timestamp, Boolean, Binary). Any other value type falls into the outer default branch and throws with the type description. The loader does not support that data type in COPY output.
Solutions
- Add a 'Select values' step before the loader to convert the unsupported field to String (or another supported type)
- Check the field types arriving at the loader (right-click > Show fields) and fix the producing step to emit standard types
- Upgrade the plugin/Pentaho version that adds support for the type, if available
- Convert specialized types (e.g. JSON, INET) to String in the source step or a Calculator/UDJE step
Example fix
// before // stream field type: JSON -> default branch -> KettleException // after (Select values / upstream conversion) valueMeta.convertData( originalMeta, originalData ); // or map JSON field to TYPE_STRING
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: reject unsupported value types before the loader runs
for ( ValueMetaInterface vm : inputRowMeta.getValueMetaList() ) {
int t = vm.getType();
boolean ok = t == ValueMetaInterface.TYPE_STRING || t == ValueMetaInterface.TYPE_NUMBER
|| t == ValueMetaInterface.TYPE_INTEGER || t == ValueMetaInterface.TYPE_BIGNUMBER
|| t == ValueMetaInterface.TYPE_DATE || t == ValueMetaInterface.TYPE_TIMESTAMP
|| t == ValueMetaInterface.TYPE_BOOLEAN || t == ValueMetaInterface.TYPE_BINARY;
if ( !ok ) throw new IllegalStateException( "Unsupported type " + vm.getTypeDesc() + " for " + vm.getName() );
} Try / catch
try {
step.processRow();
} catch ( KettleException e ) {
if ( e.getMessage().contains( "doesn't handle the type" ) ) {
// insert a Select values step to convert the offending field
}
} Prevention
- Convert exotic types (JSON, INET, etc.) to String before bulk loading
- Inspect incoming row types in Spoon before configuring the loader
- Keep upstream steps emitting standard Kettle types
When it happens
Trigger: A stream field whose ValueMetaInterface type is not one of the implemented types (e.g. TYPE_INET, TYPE_JSON, TYPE_ENUM depending on version) reaches writeRowToPostgres via processRow.
Common situations: Upstream steps emitting newer Kettle types the bulk loader was never updated for; JSON/UUID-ish data typed as specialized ValueMeta instead of String; custom value meta plugins feeding the loader.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- BaseStep.SafeMode.Exception.MixingTypes
- dbInterface.getUnsupportedTableOutputMessage()
- DynamicSQLRow.Exception.TemplateReturnDataTypeError
- ElasticSearchBulk.Error.NoJsonFieldFormat
- Function MOD only works with numeric data
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/bf29b7ba1d97b1a5.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/postgresql-db-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/pgbulkloader/PGBulkLoader.java:414
case ValueMetaInterface.TYPE_NUMBER:
if ( valueMeta.isStorageBinaryString() ) {
pgCopyOut.write( (byte[]) valueData );
} else {
pgCopyOut.write( Double.toString( valueMeta.getNumber( valueData ) ).getBytes( clientEncoding ) );
}
break;
case ValueMetaInterface.TYPE_BIGNUMBER:
if ( valueMeta.isStorageBinaryString() ) {
pgCopyOut.write( (byte[]) valueData );
} else {
BigDecimal big = valueMeta.getBigNumber( valueData );
if ( big != null ) {
pgCopyOut.write( big.toString().getBytes( clientEncoding ) );
}
}
break;
default:
throw new KettleException( "PGBulkLoader doesn't handle the type " + valueMeta.getTypeDesc() );
}
}
}
// Now write a newline
//
pgCopyOut.write( data.newline );
} catch ( Exception e ) {
throw new KettleException( "Error serializing rows of data to the COPY command", e );
}
}
protected void verifyDatabaseConnection() throws KettleException {
// Confirming Database Connection is defined.
if ( meta.getDatabaseMeta() == null ) {
throw new KettleException( BaseMessages.getString( PKG, "PGBulkLoaderMeta.GetSQL.NoConnectionDefined" ) );
}View on GitHub (pinned to f3058517a1)