This is why development estimates are hard: Unexpected resolution in the DNS area

Sebastian Rogers
3 min readMay 24, 2023

TL;DR When you upgrade to node 18 you will find that localhost no longer resolves to 127.0.0.1 as it uses IP6 by default.

A frequent question you’ll be asked as a developer is why did it take so long? If you’re unlucky it’ll be accompanied by ‘you said it would be done by Tuesday’.

Here’s a good example of a chain of events that resulted in loosing half a day. Who was at fault? Lots of people.

The problem: Tests failed in GitHub Actions

I made a ‘small change’ in an Azure Function, I added a new Function that allowed access to a new collection of data. It was almost identical to several other similar functions.

I ran the, now extended, test suite on the development machine and it all passed.

Confident I pulled the change request and made a cup of coffee.

When I got back the automated GitHub action that deploys to the shared Development system had failed.

Odd it worked a couple of months ago, but I did have to update one of the npm packages, as a result of a security notice, and that has dependencies.

Solution 1: Use a different fetch implementation

Okay so the issue is fetch and that the implemntation I use node-fetch is a commonjs module, although it now seems to be an ESM, but I know that in Node 17 fetch became part of the core API and Node 18 is released and stable so I’ll upgrade to that. See The Fetch API is finally coming to Node.js — LogRocket Blog for more details.

The only thing fetch is actually used in is the testing, so swapping one implementation for another is a low risk option.

I did this and then reran the test suite and got:

Solution 2: What else has changed?

Okay unexpected. More coffee needed.

It took quite a while, a test suite that ran against a remote rather than local copy of the Azure Function and this Stack Overflow (visual studio code — Unable to call http://localhost Azure Function from https://localhost node app — Stack Overflow) to work it out.

In Node 18 the DNS resolution uses IP6, reasonable, rather than IP4 so what had been resolving to 127.0.0.1 now resolves to ::1 and the Azure Local Function emulator rejects it.

The solution, whilst we wait for Azure to resolve this issue, really using IP6 as default does feel right these days, was to change the call from http://localhost:7071/api/Function to http://127.0.0.1:7071/api/Function.

Changed the GitHub actions to use Node 18 rather than Node 16, performed another Pull Request and this time it deployed and ran the tests successfully.

Started at 0900, was sitting down to write this blog at 1400, but I did have a meeting and lunch in between.

Nowhere in the estimates did it say ‘Resolve issues caused by Node 17 changing the default DNS resolution mechanism — 1/2 day’.

That’s why all software estimates lie.

TL;DR When you upgrade to node 18 you will find that localhost no longer resolves to 127.0.0.1 as it uses IP6 by default.

--

--

Sebastian Rogers

Technical Director for Simple Innovations Ltd. First paid for code in 1980, but still has all his own hair.