Skip to main content

This content has been archived and is no longer being updated. Links may not function; however, this content may be relevant to outdated versions of the product.

Support Article

PDF Generation Failure



You receive the following error when using the PRPC OutOfBox Activity "GenerateEform":

Status fail  
Message INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified.[...]

Error Messages

Check the logfile for the corresponding full exception (abridged here) similar to the following:

2015-01-12 13:46:11,770 [ttp-bio-6220-exec-23] [  STANDARD] [      Gcsfw:01.01.01] (ngineinterface.service.HttpAPI) ERROR lpritjw7| [email protected] - PRRuntimeError
Caused by: Unable to generate new eForm document.
    at com.pega.pegarules.integration.engine.internal.util.PREFormUtils.generatePopulatedEForm(
    at com.pegarules.generated.activity.ra_action_generateeform_975d8f62152ad2070b9e6b22e61e6ead.step1_circum0(
    at com.pegarules.generated.activity.ra_action_generateeform_975d8f62152ad2070b9e6b22e61e6ead.perform(
Caused by: org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. 
    at com.lowagie.text.pdf.XfaForm$Xml2SomDatasets.insertNode(Unknown Source)
    at com.lowagie.text.pdf.AcroFields.setField(Unknown Source)
    at com.lowagie.text.pdf.AcroFields.setField(Unknown Source)
    at com.pega.pegarules.integration.engine.internal.util.PREFormUtils.generatePopulatedEForm(
    at com.pega.pegarules.integration.engine.internal.util.PREFormUtils.generatePopulatedEForm(
    at com.pega.pegarules.integration.engine.internal.util.PREFormUtils.generatePopulatedEForm(

Steps to Reproduce

Upload your example input 'Eform' PDF to PRPC; create an 'Eform' mapping form and run the OOTB activity "GenerateEform".
[ ]

Root Cause

PRPC uses a third-party library 'itext' to read and write PDF 'Eform' documents.
It was found in this case that if the input document contains fields ("Acrofields") that contain special (in particular '#' [hash/pound symbol]) characters and/or accented characters ; then the itext library will throw such an error.

It was narrowed down to being an issue with the Library in this case, by creating a standalone test case (outside of PRPC) - and the same exception was generated.


In this case: it was found that by editing the input PDF file (using an appropriate third-party editor/generator) and ensuring that no field names ("Acrofields") contain special characters or accented characters, that the itext library (and then subsequently the PRPC actitivty "GenerateEform") was able to process the input file and correctly produce the 'filled-in' output PDF 'EForm'.

The EForm PDF 'mapping wizard' will allow you to query the 'Acrofields' in the input document; alternatively you can use the 'itext' library directly to do this. (See below).


If you experience this error (or indeed any related error) , you may wish to re-test outside of PRPC using a standalone Java program - which uses the same version of the ITEXT library for comparision.
To do this:

1. Confirm the version of 'itext' on your PRPC system using the following SQL query:

select distinct(pzjar) from PR_ENGINECLASSES
where upper(pzjar) like '%TEXT%';

[PRPC62SP2 uses V2.0.8, PRPC717 used V2.1.7 for instance].

2. Construct a Java Project (some example code given below) that include the correct version of the ITEXT library, for instance the following Maven dependency:


Use the same input file as your PRPC testing: confirm (or otherwise) you experience the same error. Use the same program to output the fields

Example Code (GCS test code only) that you may wish to reference in order to build a standalone test:
(Requires both 'itext' and 'log4j' dependencies).

package com.pega.gcs.pdftest;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfFormField;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

public class App {

    private static Logger oLog = Logger.getLogger(App.class);
    private String inPDF;
    private File outPDF;
    private byte[] inMemPDF;
    private PdfReader aPdfReader;

    public App() {

    public static void main(String[] args) {
        String[] infiles = {"input_file_1.pdf", "input_file_2.pdf"};
        for (String infile : infiles) {
            App app = new App();
            app.setOutPDF("output_" + app.inPDF, true);


    public void setInPDF(String inPDF) {"Looking for PDF:" + inPDF);
        try {
            this.inPDF = inPDF;
            InputStream is = this.getClass().getClassLoader().getResourceAsStream(inPDF);
            aPdfReader = new PdfReader(is);
  "Found PDF:" + inPDF);

        } catch (Exception e) {
            RuntimeException rte = new RuntimeException("Error when trying to read from resource:" + inPDF + " (is it available in the CLASSPATH?)", e);
            oLog.error(rte, rte);;
            throw rte;

    private List<String> getEFormFieldList() {"Iterating fieldnames contained in " + inPDF);
        AcroFields acroFields = aPdfReader.getAcroFields();
        Map fields = acroFields.getFields();
        List<String> result = new ArrayList<String>();

        Iterator itr = fields.keySet().iterator();
        int counter = 0;
        while (itr.hasNext()) {
            String fieldname = (String);
   + ": Found Field: " + fieldname);
        }"Finished Iterating fieldnames contained in " + inPDF);
        return result;

    public void markAllEFormFieldsReadOnly() {"Marking Fieldnames are readonly ");
        try {
            List fieldList = getEFormFieldList();

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfStamper stamper = createGenerationStamper(aPdfReader, baos);
            AcroFields acroFields = stamper.getAcroFields();
            Iterator it = fieldList.iterator();
            while (it.hasNext()) {
                String nextName = (String);
                try {
          "Setting field value:" + nextName);
                    acroFields.setField(nextName, "120525");
          "Setting field:" + nextName + " to readonly");
                    acroFields.setFieldProperty(nextName, "fflags", PdfFormField.FF_READ_ONLY, null);
                } catch (Exception e) {
          "Setting field:" + nextName);
                    RuntimeException rte = new RuntimeException("could not set the value", e);
                    oLog.error(rte, rte);
            inMemPDF = baos.toByteArray();
        } catch (Exception ex) {
            RuntimeException rte = new RuntimeException("Unable to mark fields read only.", ex);
            oLog.error(rte, rte);
            throw rte;

    // Creates a PdfStamper in "append mode," which sets the output version to the input version. ('\0' means 'keep version')
    private PdfStamper createGenerationStamper(PdfReader aPdfReader, ByteArrayOutputStream baos) throws DocumentException,
            IOException {
        return new PdfStamper(aPdfReader, baos, '\0', true);

    public void writeOutputBytes() {"Attempting to write out modified PDF to file:" + this.getOutPDF());
        try {
            FileOutputStream fos = new FileOutputStream(this.outPDF);
  "Completed writing out of modified PDF to file:" + this.getOutPDF());
        } catch (Exception e) {
            RuntimeException rte = new RuntimeException("Error writing out PDF", e);
            oLog.error(rte, rte);
            throw (rte);


    public String getOutPDF() {
        try {
            return this.outPDF.getCanonicalPath();
        } catch (Exception e) {
            RuntimeException rte = new RuntimeException("error running getOutPDF ", e);
            throw rte;

    public void setOutPDF(String outPDF, boolean clobber) {
        try {
            this.outPDF = new File(outPDF);
  "Setting output filename to:" + this.outPDF.getCanonicalPath() + " (clobber=" + clobber + ")");
            if (this.outPDF.exists()) {
      "Output file :" + outPDF + " already exists");
                if (clobber) {
          "Clobber set: deleting existing file");
                } else {
                    RuntimeException rte = new RuntimeException("Clobber not set, will not delete existing file");
                    throw (rte);
        } catch (Exception e) {
            RuntimeException rte = new RuntimeException("Could not set Output file to " + outPDF, e);
            throw rte;



Published January 31, 2016 - Updated October 8, 2020

Was this useful?

0% found this useful

Have a question? Get answers now.

Visit the Collaboration Center to ask questions, engage in discussions, share ideas, and help others.

Did you find this content helpful?

Want to help us improve this content?

We'd prefer it if you saw us at our best.

Pega Community has detected you are using a browser which may prevent you from experiencing the site as intended. To improve your experience, please update your browser.

Close Deprecation Notice
Contact us