pentaho/pentaho-kettle · error · IOException

: Unable to serialize data type to XML

Error message

 : Unable to serialize data type to XML 

What it means

In ValueMetaBase.getXML (data of storage type NORMAL), the object's data type is mapped to an XML string via a switch. If the data type is not among the supported XML-serializable types (it hits the default branch), an IOException is thrown with this message. It means this value's type has no defined XML representation.

Solutions

  1. Align Kettle/Pentaho versions so both designer and runtime support the value type's XML serialization.
  2. Change the field to a supported type (e.g. use Date instead of Timestamp, String instead of Inet) before serializing.
  3. If a plugin introduced the type, upgrade or patch the plugin to provide XML serialization support.
  4. Validate the metadata XML/file for a corrupted type value and regenerate it.

Example fix

// before
ValueMetaBase vm = new ValueMetaBase("when", ValueMetaInterface.TYPE_TIMESTAMP); // hits default branch
// after
ValueMetaBase vm = new ValueMetaBase("when", ValueMetaInterface.TYPE_DATE);
Defensive patterns

Strategy: validation

Validate before calling

int[] ok = { TYPE_STRING, TYPE_NUMBER, TYPE_INTEGER, TYPE_DATE, TYPE_BIGNUMBER, TYPE_BOOLEAN, TYPE_BINARY, TYPE_TIMESTAMP, TYPE_INET /* if engine supports */ };
if (vm.getStorageType() == STORAGE_TYPE_NORMAL
    && Arrays.stream(ok).noneMatch(t -> t == vm.getType())) {
  vm.setType(TYPE_STRING); // normalize unsupported types before export
}

Type guard

boolean hasXmlSerializableType(ValueMetaInterface vm) {
  return vm.getType() == ValueMetaInterface.TYPE_STRING
      || vm.getType() == ValueMetaInterface.TYPE_NUMBER
      || vm.getType() == ValueMetaInterface.TYPE_INTEGER
      || vm.getType() == ValueMetaInterface.TYPE_DATE
      || vm.getType() == ValueMetaInterface.TYPE_BIGNUMBER
      || vm.getType() == ValueMetaInterface.TYPE_BOOLEAN
      || vm.getType() == ValueMetaInterface.TYPE_BINARY;
}

Try / catch

try {
  String xml = valueMeta.getXML();
} catch (IOException e) {
  if (e.getMessage().contains("Unable to serialize data type to XML")) {
    throw new KettleException("Field '" + valueMeta.getName() + "' type " + valueMeta.getTypeDesc()
        + " is not supported by this engine version; upgrade or convert the field", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getMetaXML()/getXML() on a value meta whose data type is TYPE_TIMESTAMP, TYPE_INET, TYPE_JSON, TYPE_AVRO or another type in the switch's default branch while storage type is NORMAL (code path where newer types were expected to be handled upstream).

Common situations: A transformation built in a newer Pentaho version (containing Timestamp/Inet fields) opened with an older engine version; custom/3rd-party plugins defining types the core XML writer does not know; corrupted metadata where the type int is out of range.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:3372

                string = XMLHandler.date2string( (Date) object );
                break;
              case TYPE_BIGNUMBER:
                string = ( (BigDecimal) object ).toString();
                break;
              case TYPE_BOOLEAN:
                string = Boolean.toString( (Boolean) object );
                break;
              case TYPE_BINARY:
                string = XMLHandler.encodeBinaryData( (byte[]) object );
                break;
              case TYPE_TIMESTAMP:
                string = XMLHandler.timestamp2string( (Timestamp)  object );
                break;
              case TYPE_INET:
                string = ( (InetAddress) object ).toString();
                break;
              default:
                throw new IOException( toString() + " : Unable to serialize data type to XML " + getType() );
            }

            break;

          case STORAGE_TYPE_BINARY_STRING:
            // Handle binary string content -- only when not NULL
            // In this case, we opt not to convert anything at all for speed.
            // That way, we can save on CPU power.
            // Since the streams can be compressed, volume shouldn't be an issue
            // at all.
            //
            string = XMLHandler.addTagValue( "binary-string", (byte[]) object );
            xml.append( XMLHandler.openTag( XML_DATA_TAG ) ).append( string ).append( XMLHandler.closeTag( XML_DATA_TAG ) );
            return xml.toString();

          case STORAGE_TYPE_INDEXED:
            // Just an index
            string = XMLHandler.addTagValue( "index-value", (Integer) object );

View on GitHub (pinned to f3058517a1)