pentaho/pentaho-kettle · error · KettleException
XML does not allow empty strings for element names.
Error message
XML does not allow empty strings for element names.
What it means
The AddXML step builds an XML document where each selected field becomes an element (or attribute). When the configured element name is empty, the code first falls back to using the field name; if the field name is also null/empty, no valid XML element name exists, so the step throws this KettleException. XML spec forbids empty element names.
Solutions
- Open the AddXML step dialog and set a valid 'Element name' for every field in the 'Fields to XML' table
- Ensure the incoming stream field has a non-empty name so the fallback (element = fieldname) succeeds
- Validate the AddXMLMeta outputFields in code before running the transformation
- Re-import/re-save the transformation metadata if the field definitions came from a corrupt repository export
Example fix
// before
OutputField f = new OutputField(); // elementName=null, fieldName=null
fields.add(f);
// after
OutputField f = new OutputField("customer", "customer", false);
f.setElementName("customer");
fields.add(f); Defensive patterns
Strategy: validation
Validate before calling
for (XMLField f : meta.getOutputFields()) {
String el = f.getElementName();
if (el == null || el.isEmpty()) {
String fb = f.getName();
if (fb == null || fb.isEmpty())
throw new IllegalArgumentException("Field with no element name and no field name in AddXML step");
}
} Type guard
boolean hasValidElementName(XMLField f) {
return (f.getElementName() != null && !f.getElementName().isEmpty())
|| (f.getName() != null && !f.getName().isEmpty());
} Try / catch
try { step.processRow(); } catch (KettleException ke) {
if ("XML does not allow empty strings for element names.".equals(ke.getMessage())) {
logError("AddXML field missing element name: fix step field table");
}
} Prevention
- Always set both a field name and element name in the Fields to XML table
- Preview the step in Spoon to catch empty field rows before production
- Validate AddXMLMeta programmatically when generating transformations via API
When it happens
Trigger: processRow encounters an outputField whose XML 'Field to XML' element name is blank AND the source stream field name is also empty — e.g. a field row with no name and no element name configured in the step dialog.
Common situations: Step metadata imported from an incomplete XML/repository definition; renamed/deleted upstream fields leaving the field name empty; programmatically built AddXMLMeta with OutputField having null elementName and fieldName.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- The tablename is not defined (empty)
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- AddSequence.Exception.NoSpecifiedMethod
- AddSequenceMeta.Exception.ErrorLoadingStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ef2ebf10d5e02f65.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/addxml/AddXML.java:117
Document xmldoc = getDomImplentation().createDocument( null, meta.getRootNode(), null );
Element root = xmldoc.getDocumentElement();
for ( int i = 0; i < meta.getOutputFields().length; i++ ) {
XMLField outputField = meta.getOutputFields()[i];
String fieldname = outputField.getFieldName();
ValueMetaInterface v = getInputRowMeta().getValueMeta( data.fieldIndexes[i] );
Object valueData = r[data.fieldIndexes[i]];
if ( !meta.isOmitNullValues() || !v.isNull( valueData ) ) {
String value = formatField( v, valueData, outputField );
String element = outputField.getElementName();
if ( element == null || element.length() == 0 ) {
element = fieldname;
}
if ( element == null || element.length() == 0 ) {
throw new KettleException( "XML does not allow empty strings for element names." );
}
if ( outputField.isAttribute() ) {
String attributeParentName = outputField.getAttributeParentName();
Element node;
if ( attributeParentName == null || attributeParentName.length() == 0 ) {
node = root;
} else {
NodeList nodelist = root.getElementsByTagName( attributeParentName );
if ( nodelist.getLength() > 0 ) {
node = (Element) nodelist.item( 0 );
} else {
node = root;
}
}
node.setAttribute( element, value );View on GitHub (pinned to f3058517a1)