Understanding the SIP Via Header

Every once in a while I feel the need to get away from SIP the architecture and write about SIP the protocol (which is a little bit like the department of redundancy department – Session Initiation Protocol Protocol).   Yes, I adore all those servers and services, but it’s the bits and bytes that attracted me to SIP in the first place.

Waylon Jennings said it best in his song, “Luckenbach, Texas.”

Maybe it’s time we got back to the basics of love.

Today, I want to share the love and write about an extremely important, but sometimes misunderstood SIP header.

When a user agent client (UAC) creates a SIP request, it must insert a Via header into that request.  The Via header identifies the protocol name (SIP), protocol version (2.0), transport type (e.g. UDP or TCP), IP address of the UAC, and the protocol port (typically 5060) used for the request.  This information allows the recipient of the request (a user agent server) to return SIP responses to the correct device.  For example, if my SIP soft-phone were to send an INVITE request, it would contain a Via similar to the following.

Via: SIP/2.0/UDP

If I were operating in a point-to-point configuration, the soft-phone that received the INVITE would  inspect the Via header to determine the location of my PC.  It would then use that information to return a “100 Trying” response.  Of course, unless I am in a lab environment, I never use SIP in a point-to-point fashion.  Here at work, there are all sorts of SIP components between my soft-phone and the soft-phone I am calling.  There is a Session Manager, Communication Manager, and perhaps a Session Border Controller between us.  Thankfully, via headers are not reserved for endpoints.  Every SIP entity uses them.

The rules for processing Via headers are very simple.  Every UAC must add its own Via header before sending a SIP request.  If there is already a Via header in the message, the UAC adds the new one at the top of the list before sending it to the next hop.

Remember that INVITE I sent in my example?  When it ends up on the called party’s device, it might contain several Via headers.  When the called party is ready to send the “100 Trying,” it simply removes the top Via header and sends the response to the indicated party.  In my work configuration, that top Via would most likely identify a Session Manager.  However, if the soft client was a remote user, it would be my company’s SBC.  It doesn’t matter, though.  Whoever receives the response will remove the top Via header and send it to the next hop.  This keeps happening until the Trying message lands on my PC.

This Via stacking allows a SIP request to pass through any number of intermediaries and every recipient of that message will know exactly how to pass back any subsequent responses.

Ah, but there’s more

To keep things simple I failed to mention something important about Via headers.  Along with the protocol and IP information, every Via header contains a “branch” parameter.  Here is that Via again with a branch parameter I pulled from a Wireshark trace.

Via: SIP/2.0/UDP; branch=z9hG4bK10_16a83292baa1de54e0b7843_I

The branch parameter must be unique across space and time for all requests sent by a user agent.  The exceptions to this rule are CANCEL and ACK for non-2xx responses.  A CANCEL will have the same branch parameter as the request it cancels.  An ACK for a non-2xx response will have the same branch parameter as the INVITE whose response it acknowledges.

The uniqueness of the branch header is used to facilitate its use as a transaction ID.  A SIP transaction is a message exchange between two user agents that starts with a request and ends with a final response.  For a simple call, the INVITE through final response is one transaction, the ACK is another transaction, and the Bye through the 200 OK is yet another transaction.  All these transactions combine to make a single dialog.

If you crave more knowledge about SIP message uniqueness, please see my blog, Let’s Play (SIP) Tag.

The branch parameter always begins with the same string of seven characters — “z9hG4bK.”  This requirement was added to identify that the branch was created in accordance with RFC 3261 and not the older RFC 2543 which did not require global uniqueness.

Okay, that’s it.  I got my protocol fix for the day.  I hope you are as thrilled as I am.

Take me on out, Waylon…

So, Baby let’s sell your diamond ring

buy some boots and faded jeans

and go away


  1. Good stuff! Keep it coming🙂

    I’ve got a question though. If a transaction as you just defined is “A message exchange between two user agents that starts with a request and ends with a final response”, and the ACK is a request in another transaction, then what’s the response to the ACK request in that new transaction?🙂

  2. Good question, Moises, and there is no good answer other than “ACK is special.” This is from RFC 3261:

    SIP Transaction: A SIP transaction occurs between a client and a server and
    comprises all messages from the first request sent from the client
    to the server up to a final (non-1xx) response sent from the server to the
    client. If the request is INVITE and the final response is a
    non-2xx, the transaction also includes an ACK to the response. The ACK for
    a 2xx response to an INVITE request is a separate transaction.

  3. Hi Andrew, thank you for taking the time to answer. Looking forward to your next post.

    1. You’re welcome. I am always happy to hear that there are people out there who care about this geeky stuff.

  4. Hello…Greetings from India…

    I’m very new to SIP testing and found your stuff very interesting and nice to read. But still I could not catch some of the words you mentioned, because I’m not well versed in English..So can I request the following posts of you to be that simple for readers like me to follow?


    1. Thank you, Priya. I am happy that you are enjoying my blog and finding value in the articles. I do my best to make them readable, but some of the subjects are quite technical and it’s hard to find simple ways to express them. However, I will keep your request in mind as I delve into new topics.

    2. Hello Priya,

      I am not a native English speaker either. I must say however that I don’t think it can get simpler. I’ve found the posts writing pristine clear. If you have trouble understanding something I suggest you use google translate and/or dictionary.com. As foreigners we need to improve our English anyways, and reading posts in English with a dictionary handy is always a good way of improving vocabulary.

      1. Thank you, Moises! I appreciate the feedback.

  5. Jesus Palacio · · Reply

    Hi Andrew , I just wanted to express my gratitude for having the opportunity to learn SIP and other subjects in your blog. Your articles made me realize some importan aspects of the protocol that are usually taken for granted. Thank you very much

    1. Thank you, Jesus! I am happy that you are enjoying my blog!

  6. Hi Andrew, Thanks for your posts and replies for the questions.
    I have a basic question related to sip via and contact header fields. what is the difference and usage of via and contact fields. Why we are sending responses to via addr ? Why can’t we send response directly to contact addr ? When to use via and when to use contact ? What are mandatory fields in sip message and their real usage ?

  7. You should not send directly to the contact header as that would bypass any component in the middle that needs to see the message. Hopefully, though, the Contact header will have changed from the originator, but you still need to follow the Via process. Lastly, the Contact header may not be there so you can’t rely on using it.

    I believe that the mandatory headers are:

    To, From, CSeq, Call-ID, Max forwards, and Via.

    Go look through my past blogs for their usage. I think I have addressed every one of them.

  8. Thank you very much. I really appriciate your quick response. Then what is the usage of contact header field ? RFC3261 says that subsequent request can be directly sent to contact addr. What happens when there is proxy inbetween ? Will UAS send subsequent msgs (like OPTIONS , HOLD ..) to proxy or cobntact addr (directly to UA) ? How it will decide to where to send such subsequent requests ?

    Thanks in Advance.

    1. If you bypass the proxies in the middle then you better be assured that they are stateless. A statefull proxy would not appreciate not seeing the subsequent messages. You may need to look for a record-route header before you route on Contact.

      1. Hi Andrew, Thanks for the clarification. And I have one more doubt regarding REGISTER request. In REGISTER request contact header filed is not a mandatory field. RFC 3261 says “A REGISTER
        request can add a new binding between an address-of-record and one or
        more contact addresses”. For suppose a UAS receives a Register request from a UAC without contact header field, How/to where UAS can send a new requests (like invite, options) to that UAC? or it can not send a new request ? how to will bind to that UAC ? Thanks for your support to clarify all my doubts till now.

  9. Honestly, I am not sure since every request message I’ve ever sent contains a Contact header. I suppose it could look at the Via headers, but this isn’t something I’ve ever had to worry about.

    The RFC sometimes documents situations that are unlikely to occur in the real world. 🙂

  10. Hi Indra , A Register request should have a contact header to create new address bindings . If a registered User want to check the address bindings( there can be multiple for a single user ) for his AOR , Register without contact header can be sent. In that case , the response to Reg , 200OK carries contact header with all the address bindings.

    1. Great point and I feel dumb for missing it. I was thinking registration and not registration checking. Thanks!

    2. Hi Deepika Thanks for the information.

  11. Hi Andrew,
    first, thanks for your informative blogs. I have been in telecom for 15 years now (first 8 years in Nortel Turkey) and I completely symphatize with your passion as to how every single parameter in every message is populated🙂 I’ve been an SS7 person most of the time, moving to IMS/SIP projects in the last couple of years, and your blogs are really helpful to me. Much appreciated.
    Quoting your blog, “An ACK for a non-2xx response will have the same branch parameter as the INVITE whose response it acknowledges”. I thnk the ACK to a provisional response is actually a PRACK, right ? That’s the way you explained it in your blog earlier.

    1. An ACK is never for a provisional response. An ACK is only for a final response (2xx — 6xx). A PRACK is only for a provisional response and never for a final response.

  12. Hi Andrew,

    I got a bye message from a B2BUA as follows (request line below)

    “BYE sip:222222@xx.xx.xx.xx:1026;alias=yy.yy.yy.yy~34468~1;ob SIP/2.0”

    Is this valid bye message?

    Here what is ‘alias’ sugnifcance ? when we need to use alias ? how can we interprit this alias in bye message ?
    What is ‘ob’ ? when we need to use this ?how can we interprit this ?

    Could you please provide your comments on this ? your comments will help me a lot.

    Thanks in advance.

    1. It looks fine to me. I am not sure of all that is happening with your call flow, but “ob” stands for outbound. An alias is another identity bound to your registered user.

      1. what is meant by ‘alias’ header filed ? how the behaviour of proxy or B2BUA when it identifies ‘alias’ field in contact header field ? when alias needs to be added in contact header ? when alias needed to add in via header ? I am still having some confusion regarding alias header field in contact header and via header ? how servers handles this ‘alias’ fields ?

  13. thank you Andrew! your explanation helped me understand a bit more the Session Initiation Protocol protocol😉

  14. Hi Andrew,

    Firstly, Thanks for making such a informative blog, it’s very helpful in understanding SIP.
    I am beginner in SIP and find it very interesting. I have some doubts:-

    1. What are conditions in which Re-INVITE is preferred over UPDATE..?
    2. What are conditions in which UPDATE is preferred over Re-INVITE.?
    3. What is main difference between contact header and via header.?

    1. Thanks, Piyush.

      For me, UPDATE is sent before a session has been established (before the 200 OK and ACK). A re-INVITE is used after the session has been established.

      A Via header identifies the path a message has taken, but it does not identify the user. The Contact header identifies the user. A single message can have lots of Via headers, but only one Contact header.

  15. Hi Andrew,

    Thanks for the reply🙂

    I have some more doubts.

    1. if CONTACT header identifies the user, then how is it different from the FROM header?

    INVITE sip:bob@biloxi.com SIP/2.0
    Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
    Max-Forwards: 70
    To: Bob
    From: Alice ;tag=1928301774
    Call-ID: a84b4c76e66710@pc33.atlanta.com
    CSeq: 314159 INVITE
    Content-Type: application/sdp
    Content-Length: 142

    Can you explain it using the above example.?

    2. For a simple call flow, say A calls B.

    A and B are registered to Unified Communication Manager.

    CM<—–180 ringing———B
    A<—180 ringing—CM
    CM<———–200 OK———B

    1. A sends an ACK to CM, but CM didn’t receive it. How CM will reacts in this case i.e. what messages will CM send to A and B.?

    2. what if CM received the ACK and forwarded to B but B didn’t receive it, How B will react?

    Thanks in advance.:-)

    1. Anytime an ACK is not received, the final response is resent. The state machines of the user agents and proxies need to account for that.

      I highly suggest you look at the SIP RFC (3261) to learn the differences between From and Contact. It’s said better there than I can say it.

  16. Hi Andrew,

    I have following basic concerns on SIP.

    1) Why Request-Line required as all the data in the request-line is available in the different header fields (like method id containing by CSEQ , version is having in the via,URI is contaioning in the via or from)?

    2) What is the exact purpose of the ‘to’ header field ?

    3) What is the exact purpose of the ‘from’ header field ?

    4) Dialog can be identified only by call-ID why ‘to’ and ‘from’ required ?

    Thanks in advance.


    1. So many questions.🙂 I highly suggest that you take a look at RFC 3261. It’s not that hard to read and it will really help you gain a good understanding of SIP.

  17. Meher Abhinay · · Reply

    Hi Andrew,

    Fantastic Blog.

    I have confusion among the following headers:

    1)Difference and usage of following fields
    a) VIA
    b) Route
    c) Record Route

    2) Difference between
    a) P-Asserted Identity
    b) P-Preferred Identity.


  18. i have a question here… could you pls look into the below example …
    in that example there are two call-id’s… but per each call call-id should be unique rite???…

    please find the below Call flow scenario


    when i was checking the same in my asterisk server, i am getting two different call-id

    A to Proxy and Proxy to B….

    Is this correct??

    If it is correct call-id should be unique for each call why its is showing two calll-id for one call???

    pls help me out…

    1. If the proxy is acting as a Back-to-Back User Agent, you will see two Call-IDs. A B2BUA acts as both client and server and will recreate every call that runs through it.

      1. but how the proxy will understand (request or response) if there is two call-id’s….??

  19. (y)… Thank you so much Andrew..

    1. Stateful proxies keep track of both call legs. However they do it is up to the software, but you can build tables that match one Call-ID to another Call-ID. It’s not difficult.

  20. karthik · · Reply

    cAN YOU TELL ME BRIEF ABOUT MAGIC COOKIE z9HG4bk… why do we use that?

    “”””””””The branch parameter always begins with the same string of seven characters — “z9hG4bK.” This requirement was added to identify that the branch was created in accordance with RFC 3261 and not the older RFC 2543 which did not require global uniqueness.””””””””””””””
    This info is already there in sip rfc.. but need it with an example or in brief.

    1. I am not sure what you need. As far as I know, the magic cookie was added to distinguish implementations based on the old RFC from the ones based on the current RFC. Since the current RFC has been around for a long time, it’s probably no longer needed, but it’s still there.

      Did I understand your question correctly or are you looking for something more?

  21. Rudraprasanna Panda · · Reply

    i saw a new parameter called “received” in via header …..can someone explain me about this plz????means when received will come in via header field?????

  22. Hi Andrewy,
    I have a doubt, in case of sip forking , will branch parameter be different for each forked message?

  23. Antenna Kaak · · Reply

    Yes, of course

  24. What is the difference between Record-Route, Route and Via?

  25. @Rudraprasanna Panda
    via = at the time of generating request UA or proxy add its own address & received is added in via when proxy or UA receives the request from different address that is specified in top via header field.


    Route = Used to provide routing info. request will use strict or loose routing

    Record-Route = force routing through proxy for all subsequent request in dialog between to UA’s. In this the URI is constructed so that URI is resolved back to the proxy server. The UAS copy the record-Route to the 200 response to the request. The UAC then stores the R-R proxy list plus contact hf if present in the 200 ok for use in the route in all subsequent request.

  26. As I’m learning SIP through various sources, when I do a google search on something in particular, you always come up and you always come up with something specific and something relevant. But most important, you explain the concept definitively and simply. I thank you.

    1. Thank you. This is a labor of love for me. 🙂

  27. Hi Andrew,

    I have question regarding to Contact header parameter ” user=phone”.
    What is the dependency to use ” user=phone” in a Contact header URI as mandatory, i.e I wonder the disadvantages of not using “user=phone” in the Contact header. I miss it in my configuration and trying to see its side effects if not used.

    Since the Contact is used for direct sending the requests, location, is the header parameter such as “user=phone” is really used in defining the location of the peer ? Is not only host part enough to identify the locational info ?

    If you can make some clearance on my concern, I would be pleased.


    Thanks a lot,

  28. Hey,
    You said transaction ID is unique except for CANCEL and ACK for 2xx responses. But in a register request too, the 200 OK has the same transaction ID as the REGISTER request.

  29. Hi Andrew,

    This is a very good and very well written article. I am really more knowledgeable of the Via header after reading your post. I really like the clarity your brought on the “branch” parameter including the exceptions that are applicable to the uniqueness of the branch parameters. Next I am going to read your let’s play sip tag article since I am more interested in the sip message uniqueness at this time.

  30. Sravanthi · · Reply

    Hi Andrew,
    Can there be a possibility where the transport protocol in the via header does not match with the Transport protocol on which the message was received For example:

    If we receive a sip request that has two via headers one with TCP and one with UDP is it valid.

    Via: SIP/2.0/TCP x.x.x.x;branch=branch1
    Via: SIP/2.0/UDP y.y.y.y;branch=branch2;port=5060

    1. Yes, that transport can and often does change from hop to hop.

  31. what is diff btnwn via and record route in simple language?

    1. Via is used to route responses whereas Route and Record-Route headers are used to route requests. User agents use Record-Route headers to build Route headers.

  32. Thank you for this wonderful article! I would be grateful if you can explain how the Route, Route-record, and Via fields relate to each other. They seem to have similar function whereby the SIP proxies add thier respective information when SIP messenges traverse them. Can you explain simply what are their main functionality differerences? Thanks.

    1. Via is used to route responses whereas Route and Record-Route headers are used to route requests. User agents use Record-Route headers to build Route headers.

  33. So, two questions. For the via header is it the originating (The calling UAC) that places the initial VIA header? Also I see many traces with multiple via’s, What other devices do and do not add a VIA? What determines what other VIA’s are attached?

    1. A VIA is always added by the UAC (or UAC half of a a BB2UA). A new one was added every time it passes through a proxy. I work a lot with Avaya, and end points, session manager, communication manager, etc. all add VIA headers.

      1. Hmm it’s odd the REGISTER i’m looking at..has multiple VIA headers, but it’s the first packet in the stream.. so how can it have multiple “hops” through proxies if it’s the first REGISTER? Some of the addresses in the VIA’s are, an ipv6 address…an 169…another 192… It’s the first packet in the capture stream, maybe there was packets prior to this… but either way, why would this device need to send a register for it’s loopback and likewise, why would it want to register it’s 169 and 192 addresses?

      2. It must not be the first packet. The original UAC should not add more than one VIA. Not sure why the loopback address is in there. That seems really odd.

      3. You were right! After some digging around, I found out that it wasn’t the first REGISTER. The first haf of the call flow was truncated for space. (it was a helpdesk ticket that I was looking at). I’m still a bit confused about why the loopback was attached to the VIA line though.

  34. Hello Andrew,

    I have a question on this topic concerning the via headers in the 100trying and the 200ok from the UAS. In my scenario, I’m receiving an invite with two via headers and one record route header. The top via header is from the same IP which is used in the record-route header and this IP is the IP i’m peering with. The second VIA header is an unknown IP to me and I assume it’s the originator of this request and my IP peer forwarded it to me and included his record-route header. My question ultimately is does the top via header HAVE TO BE REMOVED in the UAS responses? You stated “the 100 trying simply removes the top via header”, but I don’t see in the RFC that this must be done. So can the 100trying and the 200ok send from the UAS include both VIA headers? If so, should the top via header in the invite be the top via header in those responses?


  35. Hello Andrew,

    I am working on IMS network,there is in traces I am able to see Update request for each call after 180 ringing.Could you please give some realtime example of update request.I am not able to find out the usages.

    Thanks in Adv

  36. Okeke Paul · · Reply

    Hi Andrew, greetins from Nigeria,

    Thanks a million times for this lovely post. The humor embedded in your explanation makes it so interesting. For real, it has been very difficult for me understanding and interpreting Wireshark SIP dumps but believe it or not. Your Posts is just equipping ME and I believe many others too. I LOVE IT

    1. Glad to be of service.

  37. Just wanted to say thank you. Your article just helped me fix a big in my code I’d been stuck on for hours.

    1. Happy to be of assistance.

  38. Couple of questions. Why do we need the branch tag to denote a call, when there is already the Call-ID header? Also, with TCP, you can’t send a response back to some other connection, you always respond on the existing connection, so is Via even needed for TCP? Or just UDP. When I’m wiresharking SIP, which is for us predominantly over TCP, I see all sorts of IP:port that are unreachable, but it doesn’t seem to matter.

  39. Niraimathi · · Reply

    Hi Andrew, Your articles are great. I see a lot of people in my company reading your articles whenever they find time and want to explore more about SIP. I have a quick question. What parameter helps to identify whether it is a re-transmitted INVITE. If it is a re-INVITE, I know it will contain a TO tag.

  40. ducnguyen · · Reply

    Hi Andrew, I must give a huge thank to you for writing this blog. It help a lot of people who try to dip their feet into sip.
    I also found this weird Via header that not include in your article, can you give me some explanation about this ? Thanks a lot for that.
    Via: SIP/2.0/UDP;received=;branch=z9hG4bK.4f851eec2cb140bd;rport=44422

  41. Hemant Budhaulia · · Reply

    excellent post andrew

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: