Quick answer for advanced users
Call WSALookupServiceEnd after you finish iterating. The error means you kept calling WSALookupServiceNext after the handle had no more data. Also check that you handle the WSA_E_NO_MORE return correctly instead of treating it as a fatal error.
Context – why this happens
You're working with the Winsock 2 Service Provider Interface (SPI). You start a service query with WSALookupServiceBegin, which gives you a handle. Then you call WSALookupServiceNext to get results one by one. Each call returns a WSAQUERYSET structure. The problem shows up when you call WSALookupServiceNext again – but there are no more results left in the query.
What's actually happening here is: the handle still exists, but the service provider returns WSA_E_NO_MORE (value 10112, hex 0x0000277E) to signal the end. This is not a crash error. It's the Winsock equivalent of "end of file". The real issue is that your code doesn't stop calling WSALookupServiceNext when it sees this error. Or you forgot to call WSALookupServiceEnd to clean up the handle.
I've seen this on Windows Server 2022 and Windows 11 when a service discovery loop runs in a tight while loop without checking the return code. One developer I helped had a bug where they used SOCKET_ERROR check but didn't check for WSA_E_NO_MORE specifically – so the loop ran forever. The exact trigger: a network service discovery app that looked for printers on a domain. After finding the last printer, the next call threw this error.
Fix steps – numbered
- Stop calling
WSALookupServiceNextwhen you getWSA_E_NO_MORE. Check the return value. If it'sSOCKET_ERROR, callWSAGetLastError(). If the last error equalsWSA_E_NO_MORE, break out of your loop. - Call
WSALookupServiceEndafter the loop. This releases the handle. Without it, you leak resources. The reason step 3 works is thatWSALookupServiceEndtells the service provider you're done. Then any futureWSALookupServiceBeginwill start fresh. - Reset the
dwSizefield inWSAQUERYSETbefore eachWSALookupServiceNextcall. The function needs the correct buffer size. SetdwSizeto the size of your buffer before each call. Many devs set it once and reuse – that breaks the second call. - Handle
WSAEFAULTseparately. If the buffer is too small,WSALookupServiceNextreturnsWSAEFAULTand setsdwSizeto the needed size. Allocate a bigger buffer and retry. Don't confuse this withWSA_E_NO_MORE. - Check your service class GUID. If you're looking for a service that doesn't exist on the network,
WSALookupServiceBeginmay succeed (returning a handle) but the first call toWSALookupServiceNextwill returnWSA_E_NO_MOREimmediately. That's correct behavior – your query matched nothing.
Alternative fixes – if the main one fails
- Use
WSALookupServiceBeginwithLUP_RETURN_NAMEandLUP_RETURN_ADDRflags only. If you request too many details (likeLUP_RETURN_BLOB), some providers fail early. Remove unnecessary flags. Test with minimal flags first. - Restart the Windows Sockets service. Open Command Prompt as admin and run:
Then restart your app. This resets the service provider state. Rarely needed, but works when a previous query left a corrupted handle.net stop winsock net start winsock - Switch to
WSASetServicefor registration. If you're the one publishing the service, make sure you callWSASetServicewithRNRSERVICE_REGISTER. If the service isn't registered,WSALookupServiceNextwill find nothing. Double-check your service name and GUID match on client and server. - Upgrade your Winsock DLL. On older systems (Windows 7, Server 2008 R2), a bug in
mswsock.dllcan causeWSA_E_NO_MOREeven with correct code. Install the latest Windows update or runsfc /scannowto repair system files.
Prevention tip
Always pairWSALookupServiceBeginwithWSALookupServiceEnd. Write a helper function that loops safely: check the return code, break onWSA_E_NO_MORE, resetdwSizeeach iteration, and always callWSALookupServiceEndon exit – even if an error happens. That single pattern prevents 90% of these errors.