Can't register softphone with correct settings



I have a Yealink phone with which I am registering on a FusionPBX server and it makes register requests like this:

Via: SIP/2.0/TCP;branch=z9hG4bK128604767;rport
From: "1001" <sip:1001@domain>;tag=1642326358
To: "1001" <sip:1001@domain>
Call-ID: 0_1934327449
Contact: <sip:1001@;transport=TCP>
Authorization: Digest username="1001", realm="domain", nonce="xxxxxxxxxxxxxxxxxxxxxxxx", ur
"sip:domain", response="xxxxxxxxxxxxxxxxxxxxxxxx", algorithm=MD5, cnonce="xxxxxxxxx", qop=auth,
Max-Forwards: 70
User-Agent: Yealink SIP-T21P_E2
Expires: 1200
Allow-Events: talk,hold,conference,refer,check-sync
Content-Length: 0

Here, “domain” is a one word domain name like “company1”. Not a tld and not a FQDN. This request is responded with a 200, registering it successfully.

Now I am trying the same settings on a mobile phone with GS Wave, I fill the fields exactly as the same I see on Yealink phone management panel. But GS wave sends two requests at first of which is the one expecting a 401 and later sends an auth. But the request content is different and it keeps getting 403 back.

First request:

Via: SIP/2.0/TCP;branch=z9hG4bK1397466438;rport
From: <sip:1001@domain@fqdn.tld:5080>;tag=829762152
To: <sip:1001@domain@fqdn.tld:5080>
Call-ID: 1068685397-12036-1@BA.B.D.BIG
Contact: <sip:1001@domain@>;expires=0
Max-Forwards: 70
User-Agent: Grandstream Wave
Content-Length: 0

Here, domain is the domain as above. fqdn.tld is the fully qualified domain name, the Fusion server which exactly appears in Yealink “host” field. This request is responded with a 401 and then it makes the second request like:

Via: SIP/2.0/TCP;branch=z9hG4bK1397466438;rport
From: <sip:1001@domain@fqdn.tld:5080>;tag=829762152
To: <sip:1001@domain@fqdn.tld:5080>
Call-ID: 1068685397-12036-1@BA.B.D.BIG
Contact: <sip:1001@domain@>;expires=0
Authorization: Digest username="1001", realm="domain@fqdn.tld", nonce="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", uri="sip:fqdn:5080", response="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", algorithm=MD5, cnonce="xxxxxxxxxxx", qop=auth, nc=00000001
Max-Forwards: 70
User-Agent: Grandstream Wave
Content-Length: 0

Both have exactly same things typed into the respective fields but the “from”, “to”, “realm”, “contact” and sip URIs are completely in different format in the requests. Why is that and how can I fix it?


Sorry, but I do not think “domain” is a one word domain or a domain at all. A one word domain is more akin to In order to be a domain, it must have a TLD (Top Level Domain) to go along with the name. If you ping “domain”, what IP does that point to?

This - “domain” - does not follow the RFC for a SIP URI and it appears that the WAVE is trying to put the scheme into the correct format for a URI.

It might help if you were to show a screenshot of how the Yealink settings are configured, but as it stands at the moment, there is nothing that I am aware of that can be done to accommodate the current implementation of how you have defined a “domain” within Fusion, which I assume is being used as multi-tenant?


Yes as you guessed, this is a context of multitenancy. There is an ambiguity on the word “domain” here. SIP URI is a FQDN but domain doesn’t have to be; as it is used to define each tenant a different context only. Like for example:

User: 1001@company1
Password: SomePass
SIP Host: fully.qualified.domain.tld:5060

and so on… Here is a screenshot from the Yealink interface:

As you will notice, it is registered with these settings. You can see the domain in username field and you can see that SIP server is a different value. (It is a public FQDN). Phone and the SIP server are not on the same network. Phone is local to me while SIP server is on a VPS. This phone works just fine.


In my mind there is no ambiguity. A domain must have a TLD; otherwise it is just a name. It does not meet any RFC and simply because Fusion may be able to work with it as such due to how they elect to control it internally does not make it a domain that can be used by anything other than fusion, but the point is that you are using a username that contains “@” which then likely triggers the host part early.

It is not clear to me what purpose the @ serves in the username. So, you might try and “escape” the @ by trying to set the username as 1020%40domain and see. If you do a wireshark capture, you should be able to expand the headers to see what the hostpart indicates and compare to that of the Yealink.


Thank you for your time. As you already know, the word “domain” has a few meanings. “Web site domain name (i.e. TLD)” is just one of them and here, it is very unrelated to what I type into the “username” box, which is completely separate from “host name” and therefore has no obligation to be a TLD. As you have first guessed, it is just a multitenancy context, by which the users of different tenants can be grouped. It has nothing to do with the SIP host.

By the way I tried escaping the @ character per your suggestion but to no result. As I said, the request format is completely different from the Yealink sends in the fields of “from”, “to”, “contact”, “realm”, “sip uri”.

What I find most interesting is that the requests Yealink makes show “company1” (i.e. “domain” of the tenant) in sip URI in the request. The phone and the SIP server is not on the same LAN and not connected through a VPN or something similar. Yealink is connecting to the server with the same SIP host (which is a FQDN) which I type into the GS Wave host field.

In particular, here are the format differences:

Yealink From and To: “1020” sip:1020@company1
Softphone From and To: "1020"sip:1020@company1@public_sip_host_fqdn:port

Yealink realm: “company1”
Softphone realm: “company1@public_sip_host_fqdn”

Yealink uri: “sip:company1”
Softphone uri: “sip:company1@public_sip_host_fqdn:port”

As another difference, I see “alias” chained on Via header of the softphone while it is absent in Yealink’s.


Again, look at the host part of the header using wireshark. The @ sign is the issue. I could see the differences in Yealink may handle the @ in the username but that is of little concern as it does not meet how the RFC reads -
A UAC may learn how to populate the To header field for a particular
request in a number of ways. Usually the user will suggest the To
header field through a human interface, perhaps inputting the URI
manually or selecting it from some sort of address book. Frequently,
the user will not enter a complete URI, but rather a string of digits
or letters (for example, “bob”). It is at the discretion of the UA
to choose how to interpret this input. Using the string to form the
** user part of a SIP URI implies that the UA wishes the name to be**
** resolved in the domain to the right-hand side (RHS) of the at-sign in**
_ the SIP URI (for instance,
process the outgoing request.

From RFC 2396 which defines how a URI is constructed and used in RGFC 2361 -
2.2. Reserved Characters

Many URI include components consisting of or delimited by, certain
special characters. These characters are called “reserved”, since
their usage within the URI component is limited to their reserved
purpose. If the data for a URI component would conflict with the
reserved purpose, then the conflicting data must be escaped before
forming the URI.

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                "$" | ","

The “reserved” syntax class above refers to those characters that are
allowed within a URI, but which may not be allowed within a
particular component of the generic URI syntax; they are used as
delimiters of the components described in Section 3.

This is why I indicated that the @ in the username/user part needs to be escaped or removed as the symbol is used to parse the message so as to identify the domain to which the message will be sent.
I did not check to see if @ is an allowable character to escape as some are and some are not. I merely provided the hex code for @ so that it could be tried.

You can contact GS support and ask if they can change, as you have nothing to lose and I also suggest you contact Fusion support and get their take on using a @ in the username for a SIP URI.

There is nothing that anyone on the forum will be able to do to get you where you want as there are no settings in WAVE to alter the parsing.


Thank you again. I am really a newbie when it comes to Network administration. I know how wireshark works but I don’t know how to capture and diagnose in this specific case.

Isn’t this in a sngrep watch aready the host part:

By the way I don’t actually think the problem is with the @ sign, I just omitted it altogether from the username, but still those headers are just the way they are, completely differently structured in comparison to Yealink requests. I mean whatever the way Fusion works, independent of that, plain text username, password and hostname completely being same (without @ sign) in Yealink and Gs Wave, why would the header formatting differ?


You are making changes that I have no visibility to and I do not know that the same change is being done within Fusion itself at the extension level. Show me one instance in any of the Fusion documentation where they have associated or use @ in a username. Show me one instance in any of the Fusion documentation where they have set a domain with a single word not using a tld.

I do not do comparisons as one normally suggests that simply because what I have works, the other must be wrong. This may or may not be the case, but the RFC which is standard that governs SIP should be followed.

And no, REGISTER SIP/2.0 is not a host part.

As stated, everything to the right of the @ is the host part.


Thank you for bearing with me.

FusionPBX documentation states that when you create a domain, you can’t login to the GUI with a plain user name anymore and that you’d have to add “@domain” to your user name to be able to login.

Since FusionPBX documentation is not very detailed, I thought the same approach must be used for extension numbers too, because it failed with plain extension number being used as user name. So I tried entering “extension@domain” to the user name field and voila! It registered (as seen on the screen shot I posted). Then I thought this was way to go with.

But I think Yealink must have worked around this non-standard way, I still find it interesting to see it can register.

Now I created a fqdn for each tenant, removed “@domain” part from the username, changed the host to use each tenant’s own fqdn rather than using only one to register all. Now it works.


The use of a domain to login into the GUI is likely true as that is not the same use case as a SIP URI.

Glad it is working. Will mark it as solved.