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
- Inspect the cause SAXException for the specific parse error (line/column number, unexpected character).
- Restore the file from Jenkins' automatic backup (config.xml.bak, config.xml.bak1, etc. in the same directory).
- If no backup exists, recreate the configuration manually through the Jenkins UI.
- 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
- Ensure atomic writes (AtomicFileWriter) for config files to prevent truncated XML.
- Monitor disk space — full disks cause partial writes.
- Regularly back up JENKINS_HOME to recover from corruption.
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.