{"record":{"id":"be618ee1d50425f4","repo":"pentaho/pentaho-kettle","slug":"jobentryxsdvalidator-error-disalloweddoctype-localized","errorCode":null,"errorMessage":"JobEntryXSDValidator.Error.DisallowedDocType (localized message)","messagePattern":"JobEntryXSDValidator\\.Error\\.DisallowedDocType \\(localized message\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"plugins/xml/core/src/main/java/org/pentaho/di/job/entries/xsdvalidator/JobEntryXSDValidator.java","lineNumber":195,"sourceCode":"            XMLConstants.FEATURE_SECURE_PROCESSING, true);\n          factorytXSDValidator_1.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n\n          // Get XSD File\n          File XSDFile = new File( KettleVFS.getFilename( xsdfile ) );\n          Schema SchematXSD = factorytXSDValidator_1.newSchema( XSDFile );\n\n          Validator xsdValidator = SchematXSD.newValidator();\n\n          // Prevent against XML Entity Expansion (XEE) attacks.\n          // https://www.owasp.org/index.php/XML_Security_Cheat_Sheet#XML_Entity_Expansion\n          if ( !isAllowExternalEntities() ) {\n            xsdValidator.setFeature( \"http://apache.org/xml/features/disallow-doctype-decl\", true );\n            xsdValidator.setFeature( \"http://xml.org/sax/features/external-general-entities\", false );\n            xsdValidator.setFeature( \"http://xml.org/sax/features/external-parameter-entities\", false );\n            xsdValidator.setProperty( \"http://apache.org/xml/properties/internal/entity-resolver\",\n              (XMLEntityResolver) xmlResourceIdentifier -> {\n                String message = BaseMessages.getString( PKG, \"JobEntryXSDValidator.Error.DisallowedDocType\" );\n                throw new IOException( message );\n              } );\n          }\n\n          // Get XML File\n          File xmlfiletXSDValidator_1 = new File( KettleVFS.getFilename( xmlfile ) );\n\n          Source sourcetXSDValidator_1 = new StreamSource( xmlfiletXSDValidator_1 );\n\n          xsdValidator.validate( sourcetXSDValidator_1 );\n\n          // Everything is OK\n          result.setResult( true );\n\n        } else {\n\n          if ( !xmlfile.exists() ) {\n            logError( BaseMessages.getString( PKG, \"JobEntryXSDValidator.FileDoesNotExist1.Label\" ) + realxmlfilename\n                + BaseMessages.getString( PKG, \"JobEntryXSDValidator.FileDoesNotExist2.Label\" ) );","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/xml/core/src/main/java/org/pentaho/di/job/entries/xsdvalidator/JobEntryXSDValidator.java#L177-L213","documentation":"When secure processing is on, the XSD validator disallows DOCTYPE declarations and installs an entity resolver that throws an IOException with the localized message JobEntryXSDValidator.Error.DisallowedDocType as soon as an external entity or DOCTYPE is encountered. This is a deliberate XXE-protection abort, not an incidental failure.","triggerScenarios":"execute() validates an XML file that contains a DOCTYPE declaration or entity reference while the disallow-doctype-decl feature is enabled; the entity resolver throws IOException immediately.","commonSituations":"Legacy XML files generated with internal DTD subsets; XML feeds that use entity shortcuts; integrating old systems that emit DOCTYPE headers.","solutions":["Remove the DOCTYPE/external entity declarations from the input XML","Regenerate the XML without DTD references","If DTDs are truly required and safe, disable the secure-processing option for this entry (understanding the XXE risk)","Pre-scan files with a filter that rejects content starting with a DOCTYPE declaration"],"exampleFix":"// before: XML with DOCTYPE fails validation\n<!DOCTYPE note SYSTEM \"note.dtd\">\n<note>...</note>\n// after: XML without DOCTYPE passes\n<note>...</note>","handlingStrategy":"validation","validationCode":"// reject DOCTYPE-bearing XML before validating\ntry ( BufferedReader r = Files.newBufferedReader( Paths.get( xmlFilename ), StandardCharsets.UTF_8 ) ) {\n  String head = r.lines().limit( 5 ).collect( Collectors.joining( \" \" ) );\n  if ( head.contains( \"<!DOCTYPE\" ) ) {\n    throw new IllegalArgumentException( \"DOCTYPE not allowed: \" + xmlFilename );\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  entry.execute( result, 0 );\n} catch ( KettleException e ) {\n  if ( e.getCause() instanceof IOException && e.getCause().getMessage().contains( \"DisallowedDocType\" ) ) {\n    logError( \"Input XML contains a DOCTYPE/external entity: \" + e.getCause().getMessage() );\n  }\n  result.setResult( false );\n}","preventionTips":["Generate XML without DOCTYPE declarations or entity references","Treat DOCTYPE in input as untrusted by default (XXE risk)","Keep secure-processing features enabled and sanitize inputs upstream","Educate upstream producers about DTD-free XML"],"tags":["xxe","security","xml-validation","doctype"],"backgroundTag":"schema-validation-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}