mDNS not working esp8226

I have tried several examples of using mdns to be able to access my server via web address instead of only with IP address. None of them work. I am using windows 10 and have read there are issues with windows 10 and MDNS. I read that downloading bonjour? May help, but no luck for me. I have tried multiple browsers and all do the same. If I try and access via ip, it works fine. If I try and use the web address from the code (ex. Esp8226.local) I get search engine result….
Not sure if this is related or not, but when I upload sketches OTA it works fine, but the esp device is labeled with an IP address in the port selection menu of the ide. Is there a way to have a name for the esp device instead of having to remember the IP address? Will the name from the mdns show there if I get it to work?

Here is an example of a sketch I have tried:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h> 
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>   // Include the WebServer library

ESP8266WiFiMulti wifiMulti;     // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'

ESP8266WebServer server(80);    // Create a webserver object that listens for HTTP request on port 80

void handleRoot();              // function prototypes for HTTP handlers
void handleNotFound();

void setup(void){
  Serial.begin(115200);         // Start the Serial communication to send messages to the computer

  wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");   // add Wi-Fi networks you want to connect to
  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");

  Serial.println("Connecting ...");
  int i = 0;
  while ( != WL_CONNECTED) { // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // Tell us what network we're connected to
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // Send the IP address of the ESP8266 to the computer

  if (MDNS.begin("esp8266")) {              // Start the mDNS responder for esp8266.local
    Serial.println("mDNS responder started");
  } else {
    Serial.println("Error setting up MDNS responder!");

  server.on("/", handleRoot);               // Call the 'handleRoot' function when a client requests URI "/"
  server.onNotFound(handleNotFound);        // When a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"

  server.begin();                           // Actually start the server
  Serial.println("HTTP server started");

void loop(void){
  server.handleClient();                    // Listen for HTTP requests from clients

void handleRoot() {
  server.send(200, "text/plain", "Hello world!");   // Send HTTP status 200 (Ok) and send some text to the browser/client

void handleNotFound(){
  server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request


I am also interested to see where this goes. I could never get mDNS working on an esp8226.


The code on the esp8266 just makes the name mapping available on the network. Additional code is required on a machine on the network to do the name resolution.

The protocol was developed by Apple and should be installed if you are running a Mac. For Windows Apple provides Bonjour. I got it by installing iTunes on my PC (Bonjour is included with iTunes). I then removed iTunes, Apple mobile services, and Apple update (in that order) to get Bonjour.

On Linux you can use Avahi.

Do you have an example of the code that should be on a machine on the network? Or, a link that provides and example of what is needed?


I just downloaded iTunes from an apple web site. Try Download and use iTunes for Windows 10 - Apple Support , I took a more convoluted route but this seems to be a good place to try. I have Windows 8.1, so used the Windows 8 version. I downloaded and installed iTunes and then the name resolution "just worked". I then removed the other pieces described since I have no interest in iTunes or other Apple apps.

Here is a sample sketch that uses a web interface to control a blinking led. You can ignore most of the stuff unrelated to mDNS. The parts of interest to you are lines 24, 153-164, 174, 192. They are mostly copied from the mDNS_Web_Server example.

/* ***********************************************************************************************
 * oldcurmudgeon November 6 2021
 * This sketch is for an ESP8266 to provide a web interface for blinking an LED
 * The onboard LED is used so no additional hardware is needed
 * It is implemented as 2 state machines. The first has the state defined by the pattern
 * being run. The state is defined by currentPattern. The state transition is done via 
 * a browser request changing newState to define the next state.
 * The second state machine defines the step in the pattern of blinks. The state transition
 * occurs when the current time for the LED state expires. When the time is up the LED toggles
 * to the other state and the time for that state starts. At the end of the pattern it is
 * started over from the beginning. 

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "your_ssid";
const char* password = "your_pw";

ESP8266WebServer server(80);

#include <string.h>
#include <Streaming.h>   //  from "Streaming by Mikal Hart" in library manager

// Pattern selection state machine variables
volatile uint16_t newPattern = 0;  //default to first pattern volatile because it is set asynchronously
uint16_t currentPattern = 0; // default first pattern

// Pattern step state machine variables
byte step = 0;                // current step in pattern default to start
unsigned long currentTime;   // current time for test
unsigned long startTime;     // start time of this step

// led on state - the onboard led is active low (when the pin is low the led
// is on). If you are using some other pin to drive the led so that the led is on when
// the pin is high this should be changed to one.
const byte LED_ON = 0; 
byte ledState = LED_ON;     // current led state default on

// led patterns - this is a series of numbers defining the led on and off times
// This example is 4 patterns of 6 changes. A zero before the end of the pattern
// indicates a short pattern that restarts when it detects a zero.
const byte NUM_PATTERNS = 4;    // number of patterns 
const byte PATTERN_LEN = 6;    // pattern length
const unsigned long pattern[ NUM_PATTERNS][PATTERN_LEN] = 
        {1500,1500,200,200,0,0},           // short pattern example 
/* ***************************************************************************
* Handle root web page
void handleRoot() {
  if (server.hasArg("pattern")){ // the browser has sent a response
    // Save new value from web page browser response  
    newPattern = server.arg("pattern").toInt();
   /* Build html page
    * The new lines (\n) are not required by the browser - they are formatting for a human 
    * looking at the page source on the browser
    * The "String((newPattern == x) ? " checked" : " ")"  construct is used to set the
    * pattern selected as checked when the web page is refreshed. If newPage is equal to
    * the value "checked" is added to the attributes, otherwise a blank is added. You can
    * see the result on the web page by right-click then select "View Page Source".
    * This will show the actual HTML sent to the browser.
  String htmlPage =
    String("<!DOCTYPE HTML>\n") 
    + "<html lang='en'>\n"
    + "<head>\n"
    + "<!-- Ignore request for nonexistent favicon -->\n"
    + "<link rel='icon' href='data:,'>\n"
    + " <meta name='viewport' content='width=device-width, initial-scale=1.0'>"
    + "<body>\n\n"
    + "<h1 style='text-align: center;'>LED Pattern Blinker</h1>\n"
    + "<div>\n"
    + "<form style='font-size: 20px'>\n"
    +   " <input type='radio' name='pattern' value='0' required"
    +  String((newPattern == 0) ? " checked" : " ")        
    +   " > Short blink<br>\n"
    +   " <input type='radio' name='pattern' value='1' required"
    +  String((newPattern == 1) ? " checked" : " ") 
    +   "> Long blink<br>\n"
    +   " <input type='radio' name='pattern' value='2' required"
    +  String((newPattern == 2) ? " checked" : " ") 
    +   "> Long Short blink <br>\n"
    +   " <input type='radio' name='pattern' value='3' required"
    +  String((newPattern == 3) ? " checked" : " ") 
    +   "> Long Long Short blink<br>\n"
    +   "<input type='submit' value='Set Pattern'>\n"
    +   "</div>\n"

  server.send(200, "text/html",htmlPage);

void handleNotFound() {
    // no clue what they sent
    String message = "File Not Found\n\n";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET) ? "GET" : "POST";
    message += "\nArguments: ";
    message += server.args();
    message += "\n";

    for (uint8_t i = 0; i < server.args(); i++) {
      message += " " + server.argName(i) + ": " + server.arg(i) + "\n";

    server.send(404, "text/plain", message);


void setup() {


  // Set up WiFi network
  WiFi.begin(ssid, password);

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
  Serial.print("Connected to ");
  Serial.print("IP address: ");

  // Set up mDNS responder:
  // - first argument is the domain name, in this example
  //   the fully-qualified domain name is "esp8266.local"
  // - second argument is the IP address to advertise
  //   we send our IP address on the WiFi network
  if (!MDNS.begin("esp8266")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
  Serial.println("mDNS responder started");

  server.on("/", handleRoot);
  // Start the server
  Serial.println("TCP server started");

  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);
  startTime = millis();      // get current time for start of pattern

void checkPattern() {
    if (newPattern != currentPattern){     // browser has sent a new pattern
        // switch to new pattern
        ledState = LED_ON;  // start with led on
        digitalWrite(LED_BUILTIN,ledState);  // start with led on
        step = 0;   // start at beginning of pattern
        currentPattern = newPattern;  // switch to new pattern
        startTime = millis();      // get current time for start of pattern

void loop() {
  server.handleClient();      // check for connection request
  // Check to see if there is a new pattern request. If the check is done here
  // the new pattern starts immediately. If you want the new pattern to start 
  // after the current pattern has completed, comment out the line below and uncomment
  // the one in the end of pattern processing
  currentTime = millis();      // get current time for compare
  if (currentTime  - startTime > pattern[currentPattern][step]) {
     // done with this step 
     ledState ^= 1;  // toggle led state
     digitalWrite(LED_BUILTIN,ledState);  // change led state       
     step++;             // next step
     startTime = currentTime;  // start next led pattern step time
     if ((step >= PATTERN_LEN)                    // end of pattern
         || (pattern[currentPattern][step]==0)){  // or short pattern
        // end of pattern processing     
        step = 0;   //restart pattern
        // Check to see if there is a new pattern request. If the check 
        // is done here the new pattern starts after the current pattern
        // has completed. (Remember to comment out the call above.)
       // checkPattern();        

I gave it a shot.... No luck for me. I can still access the server via the local ip address. But when I type in "esp8266.local" I assume this is what you were using? I just get search engine results. I did have to remove the
#include <string.h>
#include <Streaming.h> // from "Streaming by Mikal Hart" in library manager

because I don't have these libraries, but I can't believe that is the issue. The blink code works fine othere than I can't access it via the name. I assume its because I had to download windows 10?

Thanks for the help!

How are you entering the name in the browser? Microsoft Edge wants to go off and do a search. Firefox may try to add www. to the front or https://..... which is a secure server which the esp8266 isn't (without a bunch more work). Try http://esp8266.local/ and see what you get

mDNS works fine here on an ESP8266.

Must have


in void loop()



It worked! I am not sure if it was:

putting the address in like this, as I was simply typing in "esp8266.local" before, but when I typed it in just as it is above it loads and works fine.

Or, it could be that my original sketch that I tried above didn't have this:

Either way it seems to be working fine now! To my other question (could be completely unrelated and I need to start a new thread for), but how do I change how the board is labeled in the port drop down menu? So, I don't have to keep up with the ip of each esp board that I use: I am talking about where the mouse is hovering in the picture below:


The OTALeds example shows this feature, though without explicit mention. The line involved is


THANKS! This seemed to work to. For one of my esp devices, but not the other. For the one that worked, I have it connected via serial cable and uploaded the OTAleds sketch you provided directly through the COM port. It then shows: "OTAleds" at 192.168.x.xx. Which is what I want.

However, when I tried to add the line

to a sketch that I already have and changed the host name variable. It did not work. I did upload it via OTA I am wondering if this is the reason it didn't work? Or, do I need more than this one line added to my existing OTA code for it to work?


Oh well yes you do of course.
I was going from the point of view that you had the whole OTA upload thing set up already.
Of course you will get away with

#include <ArduinoOTA.h>

But really you should have all of what is in the BasicOTA sketch or you will not be able to do OTA uploads, which is what the menu is for.
Just in case, check this tutorial if you are having trouble.

I do have the rest of the OTA code up and running. Well, atleast the part that allows me to upload sketches via OTA (wirelessly)... I was thinking maybe it will only work if you have the esp device connected directly to a com port and upload it that way and not upload OTA. But, I am not sure this is the case.

In that case, adding


within a sketch that allows OTA updates, should work just fine (as you can see it is commented out in the BasicOTA sketch and so is the password.

I think I figured it out. when I first added the line below to my code:


I added it after the line:

  ArduinoOTA.begin();   //This is for OTA uploading sketch

Once I went back and put the line:



  ArduinoOTA.begin();   //This is for OTA uploading sketch

It worked fine! Thanks so much for all the help!!

Edit: I tried to give everyone here the solution check since I had multiple issues, but it would not let me. I do appreciate all!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.