DnsClient.NET: DnsResponseException: Trying to read truncated (invalid) response
I’m trying to query a nameserver (40.90.4.1:53 (Udp: 512)
) for a TXT
record and getting the following:
DnsClient.DnsResponseException: Unhandled exception ---> System.IndexOutOfRangeException: Cannot read that many bytes: '43'.
at DnsClient.DnsDatagramReader.ReadBytes(Int32 length)
at DnsClient.DnsRecordFactory.ResolveTXTRecord(ResourceRecordInfo info)
at DnsClient.DnsRecordFactory.GetRecord(ResourceRecordInfo info)
at DnsClient.DnsMessageHandler.GetResponseMessage(ArraySegment`1 responseData)
at DnsClient.DnsUdpMessageHandler.Query(IPEndPoint server, DnsRequestMessage request, TimeSpan timeout)
at DnsClient.LookupClient.ResolveQuery(IReadOnlyCollection`1 servers, DnsMessageHandler handler, DnsRequestMessage request, Boolean useCache, LookupClientAudit continueAudit)
--- End of inner exception stack trace ---
at DnsClient.LookupClient.ResolveQuery(IReadOnlyCollection`1 servers, DnsMessageHandler handler, DnsRequestMessage request, Boolean useCache, LookupClientAudit continueAudit)
at DnsClient.LookupClient.QueryInternal(IReadOnlyCollection`1 servers, DnsQuestion question, Boolean useCache)
at DnsClient.LookupClient.QueryServer(IReadOnlyCollection`1 servers, String query, QueryType queryType, QueryClass queryClass)
at DnsClient.LookupClient.QueryServer(IReadOnlyCollection`1 servers, String query, QueryType queryType, QueryClass queryClass)
It happens after a few retries, so I think it might be rate limiting / throttling. In this issue https://github.com/MichaCo/DnsClient.NET/issues/22 you mentioned that it’s a sign of an invalid/incomplete message, so it would be great if you could print the raw response in such cases. This way we have more debugging information to work with other than “bad message”.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 28 (13 by maintainers)
Commits related to this issue
- Finalizing new error handling and better logging and more unit testing. see #60. + unit tests for all the good and bad truncation handling added see #52 — committed to MichaCo/DnsClient.NET by MichaCo 4 years ago
- Improved Error and EDNS handling (#62), ContinueOnEmptyResponse (#64) * changed how opt records are created and used. Added configuration to disable EDNS and to set the requested buffer size and DnsS... — committed to MichaCo/DnsClient.NET by MichaCo 4 years ago
The changes are now released on NuGet https://www.nuget.org/packages/DnsClient/1.3.0
Looks great!
One thing that looks strange is that the second resolution attempt still says UDP?
Well, obviously this is incomplete data, the header states there are 18 answers.
The data contains 8 of those answers. Reading the 9th answer then fails.
The suspicious thing here is that the array is exactly 512 bytes, which is exactly the magic number which defines the limit of a DNS UDP payload in the classic DNS spec (before EDNS0).
There are still a lot of proxies and routers and firewalls artificially truncating the payload.
Per spec the expectation here is that a server sets a header flag indicating the result is truncated. That flag is getting respected by this library, and then falls back to TCP to run the same request over TCP again…
In your case though, that flag is not set which is actually not a valid response.
My assumption is that you are using some DNS proxy or router or firewall which alters the UDP payload between your machine and the server in Azure. Something just truncates the response from the server. Because, I cannot reproduce it with my network. If I call your server, it sends the complete result (1071 bytes) over UDP. The EDNS0 options even indicate that the server supports up to 4000 bytes (4000 is pretty unusual though, the standard maximum is 4096).
If the “middlebox” in your network would just remove the OPT record, the server would probably return a valid truncated result, but this doesn’t seem to be the case.
You could try to set the LookupClient’s settings to use TCP only, which would not even try the UDP path. At least to see if it works.
I will re-open this issue as it turns out it is in fact something different. My plan is to add an option to disable EDNS0 and maybe add some fallback to TCP even though the response is invalid. Not sure about the last part yet, I couldn’t find any good documentation of what a Client should do exactly in that scenario.
Yea, I used
_acme-challenge-test
which returned 18 TXT records consistently in 1000s of requests.Regarding printing the error details. That sounds like a great idea but isn’t that trivial I think. Have to take a look.