pentaho/pentaho-kettle · error · KettleException
PGBulkLoader doesn't know how to handle timestamp (neither…
Error message
PGBulkLoader doesn't know how to handle timestamp (neither passthrough, nor date or datetime for field
What it means
Same internal switch as the date case but for fields of ValueMetaInterface.TYPE_TIMESTAMP: writeRowToPostgres found a timestamp field whose data.dateFormatChoices[i] is not one of passthrough/date/datetime, so it throws. It means the timestamp field's format choice was never mapped to a supported option.
Solutions
- Set an explicit Date mask (date/datetime/passthrough) for the timestamp field on the step's Fields tab and re-save
- Check the stored date_mask for the field in the ktr XML or repository and correct it
- Rebuild the field mapping via 'Get Fields' so new timestamp fields get default choices
- Initialize defaults in meta code so timestamps always map to a valid choice
Example fix
// before // field added later, dateFormatChoices[i] never set // after (in meta.getFields/allocate) data.dateFormatChoices[i] = meta.getFieldDateMaskAsInt( i ); // e.g. pass/date/datetime enum
Defensive patterns
Strategy: validation
Validate before calling
// same check for timestamp fields
for ( int i = 0; i < meta.getFieldStream().length; i++ ) {
String mask = meta.getFieldDateMask()[i];
if ( mask == null || mask.isEmpty() ) {
throw new IllegalStateException( "Missing date mask for field " + meta.getFieldStream()[i] );
}
} Try / catch
try {
step.processRow();
} catch ( KettleException e ) {
if ( e.getMessage().contains( "doesn't know how to handle timestamp" ) ) {
// set a valid mask for the named timestamp field and re-run
}
} Prevention
- Re-run 'Get Fields' after upstream changes add timestamp fields
- Keep masks as recognized constants, never free text
- Re-save metadata after Pentaho/plugin upgrades
When it happens
Trigger: A TYPE_TIMESTAMP field is processed with an uninitialized or unrecognized dateFormatChoices[i], usually because its date_mask metadata was missing or stored with a value the loader doesn't recognize.
Common situations: Transformations exported/imported across Pentaho versions where timestamp masks were serialized differently; timestamp fields added by upstream steps after the mapping was built and never configured; corrupted repository attributes.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- No fields defined to load to database
- PGBulkLoader doesn't know how to handle date (neither…
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- AddSequence.Exception.NoSpecifiedMethod
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/3a404c03e067bbc2.
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:393
//
case PGBulkLoaderMeta.NR_DATE_MASK_DATE:
String dateString = data.dateMeta.getString( valueMeta.getDate( valueData ) );
if ( dateString != null ) {
pgCopyOut.write( dateString.getBytes( clientEncoding ) );
}
break;
// Convert to a "YYYY-MM-DD HH:MM:SS.mmm" format
//
case PGBulkLoaderMeta.NR_DATE_MASK_DATETIME:
String dateTimeString = data.dateTimeMeta.getString( valueMeta.getDate( valueData ) );
if ( dateTimeString != null ) {
pgCopyOut.write( dateTimeString.getBytes( clientEncoding ) );
}
break;
default:
throw new KettleException( "PGBulkLoader doesn't know how to handle timestamp (neither passthrough, nor date or datetime for field " + valueMeta.getName() );
}
break;
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 ) );
}
}View on GitHub (pinned to f3058517a1)