jenkinsci/jenkins · error · IOException

Failed to detect encoding of {}

Error message

Failed to detect encoding of {}

What it means

Wraps SAXException thrown during XML encoding detection in XmlFile.sniffEncoding() — a method that parses the XML declaration (<?xml ... encoding=...?>) using a SAX reader with a custom handler (Eureka). If the SAX parser fails to parse the file at all, a SAXException is thrown and wrapped. Note: InvalidPathException is wrapped separately as a plain IOException, and ParserConfigurationException is wrapped as AssertionError (impossible for a standard JDK).

Source

Thrown at core/src/main/java/hudson/XmlFile.java:370

                private void attempt() throws Eureka {
                    if (loc == null)   return;
                    if (loc instanceof Locator2 loc2) {
                        String e = loc2.getEncoding();
                        if (e != null)
                            throw new Eureka(e);
                    }
                }
            });
            // can't reach here
            throw new AssertionError();
        } catch (Eureka e) {
            if (e.encoding != null)
                return e.encoding;
            // the environment can contain old version of Xerces and others that do not support Locator2
            // in such a case, assume UTF-8 rather than fail, since Jenkins internally always write XML in UTF-8
            return "UTF-8";
        } catch (SAXException e) {
            throw new IOException("Failed to detect encoding of " + file, e);
        } catch (InvalidPathException e) {
            throw new IOException(e);
        } catch (ParserConfigurationException e) {
            throw new AssertionError(e);    // impossible
        }
    }

    /**
     * {@link XStream} instance is supposed to be thread-safe.
     */

    private static final Logger LOGGER = Logger.getLogger(XmlFile.class.getName());

    private static final HierarchicalStreamDriver DEFAULT_DRIVER = XStream2.getDefaultDriver();

    private static final XStream DEFAULT_XSTREAM = new XStream2(DEFAULT_DRIVER);
}

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Inspect the cause SAXException for the specific parse error (line/column number, unexpected character).
  2. Restore the file from Jenkins' automatic backup (config.xml.bak, config.xml.bak1, etc. in the same directory).
  3. If no backup exists, recreate the configuration manually through the Jenkins UI.
  4. Check disk health and write permissions to prevent future partial writes.
Defensive patterns

Strategy: validation

Validate before calling

// Validate file is valid XML before sniffing encoding
try (InputStream is = Files.newInputStream(file.toPath())) {
    byte[] head = is.readNBytes(5);
    if (head.length < 5 || head[0] != '<') {
        throw new IOException("File does not appear to be XML: " + file);
    }
}

Try / catch

try {
    String encoding = xmlFile.sniffEncoding();
} catch (IOException e) {
    if (e.getCause() instanceof SAXException) {
        // File is not valid XML — assume UTF-8 as fallback or restore from backup
        encoding = "UTF-8";
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The SAX reader throws SAXException while attempting to read the XML declaration — this happens when the file is not valid XML at all (e.g., binary data, truncated content, null bytes, or completely malformed structure before the parser can determine encoding).

Common situations: Config file was corrupted by a partial write (Jenkins killed mid-save); file is empty or contains only null bytes; file was overwritten with non-XML content (e.g., a binary download saved to a config.xml path); encoding issues at the byte level that prevent the SAX parser from even starting.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/cd7635a8232f3738. Report an issue: GitHub.