{"record":{"id":"1a42e61d53a89145","repo":"pentaho/pentaho-kettle","slug":"template-format-mismatch-template-has-extension-templateext","errorCode":null,"errorMessage":"Template Format Mismatch: Template has extension: \" + templateExt + \", but output file has extension: \" + meta.getExtension() + \". Template and output file must share the same format!","messagePattern":"Template Format Mismatch: Template has extension: \" \\+ templateExt \\+ \", but output file has extension: \" \\+ meta\\.getExtension\\(\\) \\+ \"\\. Template and output file must share the same format!","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/excel/core/src/main/java/org/pentaho/di/trans/steps/excelwriter/ExcelWriterStep.java","lineNumber":867,"sourceCode":"  }\n\n  /**\n   * Creates a new Excel file\n   */\n  private void createFile() throws KettleException, IOException {\n\n    if ( meta.isCreateParentFolders() && !data.file.getParent().exists() ) {\n      data.file.getParent().createFolder();\n    }\n\n    // if template file is enabled\n    if ( meta.isTemplateEnabled() ) {\n      // handle template case (must have same format)\n      // ensure extensions match\n      String templateExt = KettleVFS.getInstance( getTransMeta().getBowl() )\n        .getFileObject( data.realTemplateFileName ).getName().getExtension();\n      if ( !meta.getExtension().equalsIgnoreCase( templateExt ) ) {\n        throw new KettleException(\n            \"Template Format Mismatch: Template has extension: \" + templateExt + \", but output file has extension: \"\n                + meta.getExtension() + \". Template and output file must share the same format!\" );\n      }\n\n      if ( KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( data.realTemplateFileName ).exists() ) {\n        // if the template exists just copy the template in place\n        copyFile( getTransMeta().getBowl(), KettleVFS.getInstance( getTransMeta().getBowl() )\n          .getFileObject( data.realTemplateFileName, getTransMeta() ), data.file );\n      } else {\n        // template is missing, log it and get out\n        if ( log.isBasic() ) {\n          logBasic( BaseMessages.getString( PKG, \"ExcelWriterStep.Log.TemplateMissing\", data.realTemplateFileName ) );\n        }\n        setErrors( 1 );\n        throw new KettleException( \"Template file missing: \" + data.realTemplateFileName );\n      }\n    } else {\n      // handle fresh file case, just create a fresh workbook","sourceCodeStart":849,"sourceCodeEnd":885,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/excel/core/src/main/java/org/pentaho/di/trans/steps/excelwriter/ExcelWriterStep.java#L849-L885","documentation":"When templates are enabled, createFile() resolves the template file's extension via VFS and compares it (case-insensitively) with the configured output extension (meta.getExtension()). POI cannot mix HSSF (xls) and XSSF (xlsx), so a mismatch between template format and output format throws this descriptive KettleException.","triggerScenarios":"Template file has extension xls but output extension is set to xlsx (or vice versa) while 'Use template' is enabled.","commonSituations":"Copying a .xls template but leaving Extension dropdown at xlsx; renaming an xls to xlsx instead of converting; switching template files without updating the extension setting.","solutions":["Set the step's Extension option to match the template file's actual extension","Convert the template to the desired format (open in Excel, Save As) so extensions agree","Verify the template file at data.realTemplateFileName really has the extension you expect (not a renamed file with wrong content)"],"exampleFix":"// before: template = report.xls, step Extension = xlsx\nmeta.setExtension(\"xlsx\");\n// after: match the template format\nmeta.setExtension(\"xls\"); // or convert report.xls to report.xlsx","handlingStrategy":"validation","validationCode":"String templateExt = KettleVFS.getInstance(bowl)\n    .getFileObject(templatePath).getName().getExtension();\nString outputExt = meta.getExtension();\nif (!outputExt.equalsIgnoreCase(templateExt)) {\n  throw new IllegalArgumentException(\"Extension mismatch: template=.\" + templateExt + \" output=.\" + outputExt);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set Extension to match the template's real extension","Convert templates with Excel Save As instead of renaming","Audit template+extension pairs when reusing step metadata across transformations"],"tags":["excel","template","format-mismatch","xls","xlsx","kettle"],"backgroundTag":"conflicting-config-options","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"}