NameSilo DNS Integration Failure

Issue Description

When Stalwart is setting automatic DNS records for NameSilo, we are getting failures.

Expected Behavior

The records should be created using the NameSilo API.

Actual Behavior

An error is given from the Scheduled Task.

Reproduction Steps

  1. Configure NameSilo Provider
  2. Add Domain
  3. Check scheduled task.

Relevant Log Output

Failed to set DNS RRSet for emytesting.net./TXT: Failed to set DNS RRSet: Parse error: Invalid XML response: invalid type: string "{\"request\":{\"operation\":\"dnsListRecords\",\"ip\":\"64.246.108.222\"},\"reply\":{\"code\":300,\"detail\":\"success\",\"resource_record\":[{\"record_id\":\"735210d93042101c80bcf814e788f32c\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"e964e73efb8c07b91b6b9e37ae985154\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"1add1ecde258692c6365f098aa8bfc86\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"3a71e70f70522359bb68543f429b33fb\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"a86376772acec19fc682df725a121ff2\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d16555ee99bcb547072e7d3b3e5a4c64\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d23ce37b5dbc98b8064fcb2328dfab2a\",\"type\":\"TXT\",\"host\":\"_domainconnect\",\"value\":\"www.namesilo.com\\/domainconnect\",\"ttl\":3600,\"distance\":0}]}}", expected struct NameSiloEnvelope; Failed to set DNS RRSet for _ua-auto-config.emytesting.net./TXT: Failed to set DNS RRSet: Parse error: Invalid XML response: invalid type: string "{\"request\":{\"operation\":\"dnsListRecords\",\"ip\":\"64.246.108.222\"},\"reply\":{\"code\":300,\"detail\":\"success\",\"resource_record\":[{\"record_id\":\"735210d93042101c80bcf814e788f32c\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"e964e73efb8c07b91b6b9e37ae985154\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"1add1ecde258692c6365f098aa8bfc86\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"3a71e70f70522359bb68543f429b33fb\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"a86376772acec19fc682df725a121ff2\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d16555ee99bcb547072e7d3b3e5a4c64\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d23ce37b5dbc98b8064fcb2328dfab2a\",\"type\":\"TXT\",\"host\":\"_domainconnect\",\"value\":\"www.namesilo.com\\/domainconnect\",\"ttl\":3600,\"distance\":0}]}}", expected struct NameSiloEnvelope; Failed to set DNS RRSet for _imaps._tcp.emytesting.net./SRV: Failed to set DNS RRSet: Parse error: Invalid XML response: invalid type: string "{\"request\":{\"operation\":\"dnsListRecords\",\"ip\":\"64.246.108.222\"},\"reply\":{\"code\":300,\"detail\":\"success\",\"resource_record\":[{\"record_id\":\"735210d93042101c80bcf814e788f32c\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"e964e73efb8c07b91b6b9e37ae985154\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"1add1ecde258692c6365f098aa8bfc86\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"3a71e70f70522359bb68543f429b33fb\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"a86376772acec19fc682df725a121ff2\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d16555ee99bcb547072e7d3b3e5a4c64\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d23ce37b5dbc98b8064fcb2328dfab2a\",\"type\":\"TXT\",\"host\":\"_domainconnect\",\"value\":\"www.namesilo.com\\/domainconnect\",\"ttl\":3600,\"distance\":0}]}}", expected struct NameSiloEnvelope; Failed to set DNS RRSet for mta-sts.emytesting.net./CNAME: Failed to set DNS RRSet: Parse error: Invalid XML response: invalid type: string "{\"request\":{\"operation\":\"dnsListRecords\",\"ip\":\"64.246.108.222\"},\"reply\":{\"code\":300,\"detail\":\"success\",\"resource_record\":[{\"record_id\":\"735210d93042101c80bcf814e788f32c\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"e964e73efb8c07b91b6b9e37ae985154\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"1add1ecde258692c6365f098aa8bfc86\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"3a71e70f70522359bb68543f429b33fb\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"a86376772acec19fc682df725a121ff2\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d16555ee99bcb547072e7d3b3e5a4c64\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d23ce37b5dbc98b8064fcb2328dfab2a\",\"type\":\"TXT\",\"host\":\"_domainconnect\",\"value\":\"www.namesilo.com\\/domainconnect\",\"ttl\":3600,\"distance\":0}]}}", expected struct NameSiloEnvelope; Failed to set DNS RRSet for autodiscover.emytesting.net./CNAME: Failed to set DNS RRSet: Parse error: Invalid XML response: invalid type: string "{\"request\":{\"operation\":\"dnsListRecords\",\"ip\":\"64.246.108.222\"},\"reply\":{\"code\":300,\"detail\":\"success\",\"resource_record\":[{\"record_id\":\"735210d93042101c80bcf814e788f32c\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"e964e73efb8c07b91b6b9e37ae985154\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"1add1ecde258692c6365f098aa8bfc86\",\"type\":\"A\",\"host\":\"@\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"3a71e70f70522359bb68543f429b33fb\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.235\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"a86376772acec19fc682df725a121ff2\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.232.24.161\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d16555ee99bcb547072e7d3b3e5a4c64\",\"type\":\"A\",\"host\":\"www\",\"value\":\"172.234.25.42\",\"ttl\":3603,\"distance\":0},{\"record_id\":\"d23ce37b5dbc98b8064fcb2328dfab2a\",\"type\":\"TXT\",\"host\":\"_domainconnect\",\"value\":\"www.namesilo.com\\/domainconnect\",\"ttl\":3600,\"distance\":0}]}}", expected struct NameSiloEnvelope;

### Stalwart Version
v0.16.x

### Installation Method
Binary (Linux)

### Database Backend
PostgreSQL

### Blob Storage
S3-compatible

### Search Engine
PostgreSQL

### Directory Backend
Internal



### I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on

### I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on

### I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I'd prefer a human-only reply, I'll add the no-ai tag to my topic.
on

Possible Root Cause:

Root cause

The error isn’t really about your DNS records — it’s a response‑format mismatch. Look at the body embedded in the error: it’s JSON ({"request":{"operation":"dnsListRecords"...}). But Stalwart’s NameSilo driver parses the response with an XML deserializer (quick_xml::de::from_str into a NameSiloEnvelope struct). When quick‑xml is handed a JSON document, it can’t find the <namesilo>/<reply> elements it expects, the whole payload collapses to a single text node, and serde reports exactly what you see: invalid type: string … expected struct NameSiloEnvelope.

So: NameSilo returned JSON, Stalwart demanded XML. Every “Failed to set … RRSet” line is the same failure — before setting any record, the driver calls dnsListRecords to diff existing records, that list call comes back JSON, and the parse blows up, so nothing downstream ever runs.

Why NameSilo is sending JSON despite type=xml

This is the interesting part. Stalwart’s driver (the dns-update crate, src/providers/namesilo.rs) does send type=xml on every request — I confirmed it in the current main and in released 0.4.1 / 0.5.0 / 0.5.4, so it’s not a version regression:

version=1&type=xml&key=…&domain=emytesting.net

Per NameSilo’s own API reference, type=xml should yield XML, and every other real‑world NameSilo client (the Go nrdcg/namesilo lib, the common PowerShell/curl DDNS scripts) sends exactly that and gets XML back. So on paper this should work.

The one concrete difference: dns-update’s shared HTTP client sets a default header on every request —

rust

headers.append(CONTENT_TYPE, HeaderValue::from_static("application/json"));

— and the NameSilo provider builds on that default client without overriding it. So each request carries Content-Type: application/json while the query string says type=xml. NameSilo’s front end appears to be doing content negotiation off the header and overriding the query param, handing back JSON. That header is the only thing distinguishing Stalwart’s requests from all the working type=xml clients, and it produces precisely this symptom. It’s effectively a bug in the dns-update NameSilo provider.

Idea that probably has been tried:

Change the

into

https://support.stalw.art/u/ken_emy if you fear cargo build, say so.