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

Most upvoted comments

The changes are now released on NuGet https://www.nuget.org/packages/DnsClient/1.3.0

Looks great!

DnsClient Verbose: 0 : [NameServer] Starting to resolve NameServers, skipIPv6SiteLocal:True.
DnsClient Verbose: 0 : [NameServer] Resolved 2 name servers: [208.67.222.222:53 (Udp: 512),208.67.220.220:53 (Udp: 512)].
DnsClient Verbose: 1 : [LookupClient] Begin query 14499 - Qs: 1 Recursion: True OpCode: Query => _acme-challenge-test.azuredns.site IN TXT on [40.90.4.1:53 (Udp: 512)]
DnsClient Verbose: 2 : [LookupClient] TryResolve 14499 => _acme-challenge-test.azuredns.site IN TXT on 40.90.4.1:53 (Udp: 512), try 1/6.
DnsClient Error: 91 : [LookupClient] Query 14499 => _acme-challenge-test.azuredns.site IN TXT error parsing the response. The response seems to be truncated without TC flag set! Re-trying via TCP anyways.
DnsClient.DnsResponseParseException: Response parser error, 512 bytes available, tried to read 43 bytes at index 504.
Cannot read bytes.
[OKOBgAABABIAAAABFF9hY21lLWNoYWxsZW5nZS10ZXN0CGF6dXJlZG5zBHNpdGUAABAAAcAMABAAAQAAADwAKilXVGJwSnl6UVdwVXBSYS1sSV92SV95M19EZUtQME1ybXlXazdWVUxSM8AMABAAAQAAADwAKilXVGJwSnl6UVdwVXBSYS1sSV92SV95M19EZUtQME1ybXlXazdWVUxSNMAMABAAAQAAADwAKypXVGJwSnl6UVdwVWQtbElfdklfeTNfRGVLUDBNcm15V2s3VlVMUnZCSTnADAAQAAEAAAA8ACsqV1RicEp5elFXcFVwUmEtbElfdklfeTNfRGVLUDBNcm15V2s3VlVMUnZhwAwAEAABAAAAPAArKldUYnBKeXpRV3BVcFJhLWxJX3ZJX3kzX0RlS1AwTXJteVdrN1ZVTFJ2c8AMABAAAQAAADwAKypXVGJwSnl6UVdwVXBSYS1sSV92SV95M19EZUtQME1ybXlXazdWVUxSdnfADAAQAAEAAAA8ACsqV1RicEp5elFXcFVwUmEtbElfdklfeTNfRGVLUDBNcm15V2s3VlVMUndlwAwAEAABAAAAPAAsK1dUYnBKeXpRV3BVcFJhLWxJX3ZJX3kzX0RlS1AwTXJteVc0N1ZVTFJ2QknADAAQAAEAAAA8ACwrV1RicEp5elE=].
   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(IReadOnlyList`1 servers, DnsQuerySettings settings, DnsMessageHandler handler, DnsRequestMessage request, LookupClientAudit audit)
DnsClient Verbose: 2 : [LookupClient] TryResolve 21318 => _acme-challenge-test.azuredns.site IN TXT on 40.90.4.1:53 (Udp: 512), try 1/6.
DnsClient Verbose: 10 : [LookupClient] Query 21318 => _acme-challenge-test.azuredns.site IN TXT on 40.90.4.1:53 (Udp: 512) received result with 18 answers.
DnsClient Verbose: 31 : [LookupClient] Response 21318 => _acme-challenge-test.azuredns.site. IN TXT opt record sets buffer of 40.90.4.1:53 (Udp: 4000) to 4000.
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvB1"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI2"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI4"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI5"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI6"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI7"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI8"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvBI9"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUd-lI_vI_y3_DeKP0MrmyWk7VULRvBI9"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRadlI_vI_y3_DeKP0MrmyWk7VULRvBI10"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyW47VULRvBI"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvs"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRva"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULR4"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRvw"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULR3"
_acme-challenge-test.azuredns.site. 60 IN TXT "WTbpJyzQWpUpRa-lI_vI_y3_DeKP0MrmyWk7VULRwe"

One thing that looks strange is that the second resolution attempt still says UDP?

DnsClient Verbose: 2 : [LookupClient] TryResolve 21318 => _acme-challenge-test.azuredns.site IN TXT on 40.90.4.1:53 (Udp: 512), try 1/6.
DnsClient Verbose: 10 : [LookupClient] Query 21318 => _acme-challenge-test.azuredns.site IN TXT on 40.90.4.1:53 (Udp: 512) received result with 18 answers.
DnsClient Verbose: 31 : [LookupClient] Response 21318 => _acme-challenge-test.azuredns.site. IN TXT opt record sets buffer of 40.90.4.1:53 (Udp: 4000) to 4000.

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.

image

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).

; EDNS: version: 0, flags:; udp: 4000

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.