The new desk phones are on the desks, the link lights are green, and every screen shows an IP address, yet not one of them has an extension, a line key or a dial tone. Getting DHCP option 66 vs 150 wrong is the usual reason, because the phone got an address and never learned where its configuration lives.

Both options tell a phone where to fetch its files. They do it in different formats, phones from different vendors look for them in different orders, and the boot sequence has several other places to fail before either option is even read. This walks through the difference, the sequence, one working configuration, and the ways it goes wrong.

What is the actual difference between option 66 and option 150?

Option 66 is the older one. RFC 2132 names it TFTP server name, gives it code 66 with a minimum length of 1, and defines it as a string of characters. It was meant to identify a TFTP server when the sname field in the DHCP header has been used for options. In practice it carries a hostname or, on phones that accept one, a full URL.

Option 150 is the TFTP Server Address option, documented in RFC 5859, an Informational memo written by an author at Cisco Systems. It contains one or more IPv4 addresses, and nothing else. The length field must be an integral multiple of 4 octets, and an option where that is not the case must be ignored. There is no scheme, no port, no path and no hostname. The RFC also states that there is currently no defined IPv6 DHCP equivalent.

The reason 150 exists is spelled out in the RFC itself. Option 66 and the sname field contain the TFTP server's hostname, which then has to be translated to an address, usually by DNS, which adds an additional point of failure for a device trying to boot. Option 150 hands the phone addresses it can use directly, and it can list more than one for redundancy. The memo goes further: when the configuration server speaks something other than TFTP, it calls option 66 inappropriate.

A few behaviors in RFC 5859 matter during troubleshooting:

  • The client asks for it by including 150 in the Parameter Request List, option 55.
  • Addresses should be listed in order of preference, and each address is tried a total of four times with a 4-second wait before the phone moves on.
  • When both options appear in the same reply, option 150 should have priority over option 66, though the RFC leaves it to the device to decide which piece of information to use.

Which phones read which option?

This is where vendor documentation, not the RFCs, decides the outcome. The following is limited to what each vendor's own guide states.

Cisco, enterprise firmware. The Cisco IP Phone 8800 Series administration guide for Unified Communications Manager tells you that when the phone uses DHCP, it obtains the TFTP server address from the DHCP server, and to check that the IP address is configured in Option 150.

Cisco, multiplatform (MPP) firmware. The MPP administration guide lists a DHCP Option To Use parameter whose default value is 66,160,159,150,60,43,125, the order in which the phone uses what the DHCP server provides. Note that this firmware tries 66 before 150, the reverse of the RFC's preference, so the same hardware behaves differently depending on which firmware it shipped with.

Yealink. Yealink's auto provisioning guide sets the priority as Zero Touch, then PnP Server, then DHCP options (for IPv4, the custom option, then option 66, then option 43), then Phone Flash. It supports FTP, TFTP, HTTP and HTTPS and uses TFTP by default, and its own deployment example puts tftp://192.168.1.100/$PN in option 66. Option 150 does not appear in its list.

Grandstream. Grandstream's SIP device provisioning guide says its products support DHCP option 66 or 43, with the provisioning server URL embedded in the option. When an HTTP URL is placed in option 66, the device will then issue HTTP requests instead of TFTP requests. The same guide notes that only certain newer product series supported that flexibility when it was written, so check the model.

What does the full boot sequence look like?

A phone that never provisions has failed at one of six steps. Each has a different symptom, which is the fastest way to tell them apart.

1. Link up and power

The phone powers from the switch or a brick and brings the link up. If nothing lights, the problem is cabling or power, not DHCP.

2. Voice VLAN from LLDP-MED or CDP

The switch tells the phone which VLAN to tag voice traffic with. On Cisco switches, the Catalyst 9200 configuration guide describes the LLDP-MED network policy TLV as the way the switch can notify a phone of the VLAN number that it should use. Cisco phones also use CDP to learn the auxiliary VLAN ID, and the MPP guide says that during startup the phone sends both CDP and LLDP-MED PDUs. If neither protocol sets a VLAN, the phone uses a manually configured VLAN ID; if there is none, no VLAN is supported. The symptom of a failure here is a phone that gets an address from the data subnet instead of the voice subnet.

3. DHCP on the voice VLAN

Once tagged, the phone sends a new DHCP request on the voice VLAN. If the DHCP server is not on that subnet, the router needs a relay; Microsoft notes that a DHCP relay agent eliminates the need for a DHCP server on every subnet. Cisco's troubleshooting steps for a phone that shows no DHCP server value point to the same place: check your IP routing and VLAN configuration.

4. Reading option 66 or 150

The DHCP reply arrives with an address and, if the scope was built correctly, the option the phone looks for. The symptom of failure is the one in the first paragraph: a valid address and nothing else happening.

5. Fetching the configuration file

The phone requests files by name. Grandstream devices request a file named cfgMAC, for example cfg000b820102ab, in lower case, and XML-capable models also request cfgMAC.xml. Yealink phones use a common boot file with the fixed name y000000000000.boot. A failure here means the phone found the server, so the problem is the file name, the folder or the protocol, not DHCP.

6. Registration

With the file loaded, the phone registers to the call server. Failures past this point are credential or SIP problems, not provisioning problems.

A worked example: twenty phones, one Windows DHCP server

Take a 20-seat accounting firm replacing old handsets with Yealink phones, on a Cisco Catalyst access switch, with a Windows Server handling DHCP. Voice will live on VLAN 100, scope 10.10.100.0, and the provisioning server is at 10.10.100.5.

On the switch, the Catalyst 9200 guide lists the LLDP global state as Disabled by default, so the first command is lldp run, followed by lldp transmit and lldp receive on the interfaces. Then the network policy: network-policy profile 1, then voice vlan 100 cos 4 inside it, then on each phone port network-policy profile 1 and lldp med-tlv-select network-policy. Verify with show network-policy profile and, once a phone is plugged in, show lldp neighbors detail.

On the DHCP server, an option value cannot be set until a definition for it exists. Microsoft's documentation for Add-DhcpServerv4OptionDefinition states plainly that an option definition must exist before an option value of that type can be configured. Run Get-DhcpServerv4OptionDefinition -OptionId 66 to see whether the server already knows the option. If it does not, add it with a -Name, -OptionId and a -Type of String. If Cisco phones on enterprise firmware are ever added, define 150 the same way with a -Type of IPAddress and the -MultiValued switch so it can hold more than one address.

Then set the value on the voice scope only, using Set-DhcpServerv4OptionValue with -ScopeId 10.10.100.0, -OptionId 66 and -Value tftp://10.10.100.5/. Microsoft documents that specifying only the ScopeId sets the value at the scope level, while specifying neither ScopeId nor ReservedIP sets it at the server level, for every scope.

On the phones, Yealink's guide puts the setting under Settings->Auto Provision, where DHCP Active must be on and the Power On mode makes the phone provision at every power-up. Plug one phone in, confirm it lands on VLAN 100, confirm the lease shows option 66, and only then unbox the other nineteen.

Where does this go wrong?

The option is on the wrong scope. The most common case. The option was added to the data scope, or at the server level, while the phones lease from the voice scope that never got it.

A URL in option 150, or a bare IP where a URL was expected. Option 150 carries only IPv4 addresses, so a URL has nowhere to go. A phone that reads only 150 will never see whatever was placed in 66. In the other direction, a bare address in option 66 leaves the protocol to the phone's default, which Yealink documents as TFTP; a server that only answers HTTPS will never see a request.

HTTPS provisioning URLs in option 66. Yealink and Grandstream document URLs in option 66, but the RFC defines the field as a TFTP server name. Whether a particular phone accepts an https URL there is a question for that model's guide. The Grandstream guide's own caveat, that only certain series honored an HTTP URL in 66, is the warning.

The voice VLAN is not advertised. LLDP disabled globally, the network policy never applied to the port, or the policy created in the wrong order. The Catalyst 9200 guide notes that if a network-policy profile is configured first, the switchport voice vlan command cannot then be applied to that interface. The phone gets an address from the data scope, where no option 66 exists.

CDP and LLDP-MED disagree. Cisco's MPP guide warns that inconsistent CDP and LLDP-MED configuration can result in an oscillating rebooting behavior as the phone switches between VLANs. A phone rebooting every few minutes on a mixed switch is the tell.

The phone keeps its old configuration. Yealink's priority list ends at Phone Flash, a server URL stored on the phone, and Cisco's guide describes an alternate TFTP server setting on the phone, useful when the phone recently moved. A phone that worked somewhere else may be dutifully fetching from that old server. Check the manual setting before blaming DHCP.

Which one should you set?

If every phone runs Cisco enterprise firmware, set option 150 with the provisioning server's IPv4 addresses in preference order. If the phones are third-party SIP phones, set option 66 with the full URL the vendor's guide shows. If the fleet is mixed, set both on the voice scope, point them at the same server, and never put a URL in 150. Then test one phone end to end before the rest come out of the box.