iflytek/astron-agent · error · AesException

-40002

-40002

Error message

XML parsing failed

What it means

XMLParse.extract parses the WeChat callback XML document and pulls out the requested fields (e.g. Encrypt). Any exception during DocumentBuilderFactory parsing or node extraction throws AesException -40002 (ParseXmlError) after a stack-trace print. decryptMsg depends on this to locate the Encrypt element, so a parse failure blocks signature verification and decryption.

Solutions

  1. Log the raw XML body and the printed stack trace to see the exact parse failure.
  2. Reject empty/non-XML bodies with HTTP 400 before calling decryptMsg/extract.
  3. Ensure the body is decoded as UTF-8 and not truncated or re-encoded by proxies or filters.
  4. Sanitize the XML of invalid control characters before parsing if senders may include them.

Example fix

// before
Object[] encrypt = XMLParse.extract(postData, new String[]{"Encrypt"}).values().toArray(); // postData may be blank
// after
if (postData == null || postData.isBlank()) {
    throw new IllegalArgumentException("empty callback body");
}
Object[] encrypt = XMLParse.extract(postData, new String[]{"Encrypt"}).values().toArray();
Defensive patterns

Strategy: try-catch

Validate before calling

if (xml == null || xml.isBlank()) throw new IllegalArgumentException("empty xml");

Try / catch

try { Object[] enc = XMLParse.extract(xml, new String[]{"Encrypt"}).values().toArray(); } catch (AesException e) { if (e.getCode() == -40002) { log.warn("XML parse error for callback body"); return ""; } throw e; }

Prevention

When it happens

Trigger: Calling extract(xml, fieldNames) with XML that the DocumentBuilder cannot parse: empty or blank string, malformed tags, invalid XML characters, wrong encoding, or a body that is not XML at all.

Common situations: Empty POST bodies from health checks or scanners hitting the WeChat callback URL; charset/encoding mismatches; XML containing entities or DOCTYPEs the parser disallows; bodies mangled by middleware before reaching decryptMsg.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/61ccf1ca76d886c9. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/XMLParse.java:53

            dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            dbf.setXIncludeAware(false);
            dbf.setExpandEntityReferences(false);
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xmltext);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            for (String key : keys) {
                NodeList nodeList = root.getElementsByTagName(key);
                if (nodeList.getLength() > 0) {
                    result.put(key, nodeList.item(0).getTextContent());
                }
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ParseXmlError);
        }
    }

    /**
     * Generate XML message
     *
     * @param encrypt Encrypted message ciphertext
     * @param signature Security signature
     * @param timestamp Timestamp
     * @param nonce Random string
     * @return Generated XML string
     */
    public static String generate(String encrypt, String signature, String timestamp, String nonce) {
        String format = "<xml>%n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>%n"
                + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>%n"
                + "<TimeStamp>%3$s</TimeStamp>%n" + "<Nonce><![CDATA[%4$s]]></Nonce>%n" + "</xml>";
        return String.format(format, encrypt, signature, timestamp, nonce);
    }

View on GitHub (pinned to 5e758547a8)