Skip to main content
DoIP handshake sequence between tester and DoIP entity: vehicle identification, TCP connect, routing activation request and the accept-or-reject response code with its denial causes, then diagnostic messages, from GSAS Micro Systems India

DoIP Routing Activation Failures: The Response Code Table

GSAS Engineering · · 13 min read

DoIP routing activation fails when the entity rejects the tester's request, and the one-byte response code says why: 0x00 unknown source address, 0x01 all TCP_DATA sockets registered and active, 0x02 a different source address on an already activated socket, 0x03 that source address active on another socket, 0x04 missing authentication, 0x05 rejected confirmation, 0x06 unsupported activation type, 0x07 the route requires TLS. 0x10 is success and 0x11 means routing is pending a confirmation step, so it is not yet success.

A DoIP session that dies at routing activation gives you one byte of explanation, and that byte names the exact check that failed inside the entity. Not every tool stack surfaces it, and a generic error in its place is why engineers burn time on cabling and TCP before checking a configuration value.

This is the lookup table for that byte, plus what a table alone cannot give you: the order the entity applies its checks in. The order matters, because two misconfigurations can both be true and you only see the code from the first check that failed.

The protocol itself, the handshake sequence, UDP discovery and the eight-byte header, is covered in our DoIP explainer. This article assumes that ground.

Where routing activation sits in the DoIP handshake

Discovery over UDP, TCP connect, routing activation, then diagnostic messages. The third step is the only one that can refuse you politely.

What the entity is deciding

Routing activation is an admission decision, not a connection check. The entity decides whether this tester source address, on this socket, asking for this activation type, may have diagnostic messages routed to the target addresses tied to that activation. The AUTOSAR Classic Platform specification of Diagnostic over IP is explicit about the yes case: the socket becomes Registered [Routing Active] for that source address, and diagnostic requests to the configured target addresses are routed from then on. Before that point, the same document says, any message other than a routing activation request, or one required for authentication or confirmation, is silently discarded.

Silently. That is the whole reason a failed activation looks like a dead vehicle rather than a refusal.

Logical addresses: tester, entity, gateway or node

Three address values are in play and they are not interchangeable.

The tester source address is yours, and goes in the request. python-doipclient documents the tester range as 0x0E00 to 0x0FFF and defaults client_logical_address to 0x0E00; the Scapy DoIP socket defaults source_address to 0xe80. Two open-source clients, two different defaults, and neither is necessarily what your vehicle expects.

The entity logical address is the vehicle side’s, returned in the response: AUTOSAR sets that field to the entity’s configured DoIPLogicalAddress. Take it from discovery or from the response, not a spreadsheet. The target address is a third thing, used in diagnostic messages after activation, and reachable only if your activation enabled it.

Gateway or node changes what sits behind all of this, a decision taken long before your bench existed, as our notes on the vehicle communication architecture and domain and zone controller hardware describe. python-doipclient’s entity status response exposes node_type, 0x00 for a gateway and 0x01 for a node, alongside max_concurrent_sockets and currently_open_sockets. Read those before arguing about socket exhaustion.

Why it surfaces as a tool error string

The response code is one byte inside payload type 0x0006, and a tool has to choose to surface it. Some do not, and report a numbered internal error instead.

That gap is visible in a public forum thread on a tool vendor’s community site. Discovery worked, the correct IP address and VIN came back, and the session failed at activate routing with an undefined error number. The checks suggested ran from entity settings through protocol version, source and target addresses, to a newer driver release, with a Wireshark capture on the doip filter as the tie-breaker. The outcome is the part worth carrying: the capture resolved it, and the cause was a bug in the ECU, not the tester configuration. Start with the tester-side checklist, and do not assume it ends there.

The response code table

How this table was built

Every denial and success code below appears in at least three of these four independent public sources: the AUTOSAR Classic Platform specification of Diagnostic over IP (R24-11, AUTOSAR_CP_SWS_DiagnosticOverIP), the Wireshark DoIP dissector value strings in packet-doip.c, and the response code enumerations in python-doipclient and Scapy. The one exception, the reserved range, is flagged in its own row. Where they disagree, the disagreement is flagged in the row rather than resolved silently. ISO 13400 itself is paid, so it is named and never quoted.

Code, meaning, first thing to change

CodeMeaning (Wireshark wording, shortened)What it means in practiceFirst thing to change
0x00Denied due to unknown source addressYour tester source address is not in the entity’s configured list. AUTOSAR specifies this code when it does not match a configured DoIPTesterSA, then a socket closeThe source address in your client, from the OEM diagnostic specification. Not a guess
0x01Denied because all concurrently supported TCP_DATA sockets are registered and activeThe entity is at its configured maximum tester connections and every existing tester answered an alive checkClose the other session. Read currently_open_sockets and max_concurrent_sockets from an entity status request
0x02Denied because an SA different from the table connection entry was received on the already activated TCP_DATA socketYou activated on this socket with one source address, then sent a second activation with a different oneOne source address per socket, or open a new connection
0x03Denied because the SA is already registered and active on a different TCP_DATA socketThe same tester address is live on another socket, and that socket answered the alive checkFind and close the other session. Check your own duplicate clients before blaming a colleague’s
0x04Denied due to missing authenticationAn authentication callback returned a failure. AUTOSAR notes the connection stays registered to your source address with routing not enabledThe OEM-specific bytes, and whether you are entitled to this activation
0x05Denied due to rejected confirmationA confirmation step returned a failure, and the socket is closedRarely a tester-side fix. Ask what the confirmation checks
0x06Denied due to unsupported routing activation typeThe activation type byte matches no activation number configured for your source addressThe activation type. Try the default first
0x07Denied due to request for encrypted connection via TLSThis route requires the secured connection. Scapy words it as the activation type requiring a secure TLS TCP_DATA socketMove to the TLS port with a proper context. A different source address will not help
0x08 to 0x0FReserved by ISO 13400Reserved in the Wireshark dissector and in Scapy; python-doipclient’s enumeration omits them entirely and AUTOSAR does not define them. This row is the one place the sources do not agreeNothing. Treat one as an entity defect and capture it
0x10Routing successfully activatedRouting is enabled for the target addresses tied to this activationNothing
0x11Routing will be activated, confirmation requiredNot success. AUTOSAR puts the connection in Registered [Pending for Confirmation]Handle the confirmation exchange. python-doipclient raises on this code at construction because it is not Success; request_activation() called later returns the response for you to handle

Reading it at a glance

Two codes are not denials, 0x10 and 0x11, and only one is success. python-doipclient raises ConnectionRefusedError if the activation it performs at construction returns anything other than Success, so 0x11 reaches your program as a refusal. Scapy raises on anything other than 0x10 too, except 0x07, which it treats as an instruction to re-activate on the TLS port.

Everything from 0x00 to 0x07 is a denial: 0x00, 0x02 and 0x03 are address problems, 0x01 is capacity, 0x06 is activation type, and 0x04, 0x05 and 0x07 are policy problems no tester setting will clear.

OEM-assigned activation types

The activation type is a single byte in the current protocol versions, and its meaning is assigned per vehicle programme. AUTOSAR models it as DoIPRoutingActivationNumber, an integer from 0 to 255 configured per routing activation container, and accepts your request only if the byte matches an activation number configured for your source address. Anything else yields 0x06.

Only a few values appear in public sources, and they do not fully agree:

ValueWiresharkpython-doipclientScapy
0x00DefaultDefaultDefault
0x01WWH-OBDDiagnosticRequiredByRegulationWWH-OBD
0xE0Central securitynot presentCentral security
0xE1not presentCentralSecuritynot present

Take 0x00 and 0x01 as safe: all three carry them and the names describe the same thing. 0xE0 is the better bet: AUTOSAR R24-11 keys its central security signalling on DoIPRoutingActivationNumber 0xE0, and Wireshark and Scapy both name 0xE0. python-doipclient is alone at 0xE1. Still do not hard-code either; the value your programme uses comes from the OEM specification. Scapy’s enumeration also duplicates “Default” at 0x16 and contains entries wider than the one-byte field it decorates (0x116, 0xe016), which cannot match on the wire, so read it as a convenience list rather than a specification.

Everything else is OEM-assigned. There is no published master list and this article will not invent one: the value your programme uses comes from your OEM or supplier diagnostic specification.

The order the entity checks in

This is what turns a code into a diagnosis. The AUTOSAR requirements chain in a fixed order, and the first failing check wins:

  1. Header and payload length. The expected payload length for a routing activation request is exactly 7 or 11 bytes. A wrong length gets NACK code 0x04 in a generic header negative acknowledgement, payload type 0x0000, not an activation response at all. For this payload type that NACK is sent in any connection state.
  2. Source address against the configured tester list. No match, 0x00, socket closed.
  3. Is this socket already activated to a different source address? Yes, 0x02, socket closed.
  4. Is this source address already registered on another connection? If so the entity alive-checks that connection. If the other tester answers, you get 0x03. If it times out, processing continues.
  5. Is the entity at its maximum tester connections? If so it alive-checks all of them. If every one answers, you get 0x01. If any times out, that connection is closed and processing continues.
  6. Activation type against the activation numbers configured for your source address. No match, 0x06, socket closed.
  7. Authentication callback, if configured. Failure gives 0x04.
  8. Confirmation callback, if configured. Pending gives 0x11, failure gives 0x05.
  9. Nothing refused it: 0x10, and the socket becomes Registered [Routing Active].

Two consequences worth internalising. You cannot see a 0x06 until your source address has been accepted, so a 0x06 is quiet good news about step 2. And 0x01 and 0x03 both depend on another tester answering an alive check, which is why the same setup can be admitted on one attempt and refused on the next.

Do not use the state of the TCP socket as evidence either way. Most denial paths in AUTOSAR are followed by a socket close, but 0x04 explicitly leaves the connection registered to your source address with routing disabled, and what your client library reports about the socket is a separate question from what the entity did.

The five failures behind most tickets

Tester source address not on the entity’s expected list

The failure with no discovery path: nothing in the vehicle identification response tells you which tester addresses the entity will accept, so this one is invisible until you send the request. Code 0x00.

Wrong target address, or a node behind a gateway addressed directly

This does not fail activation at all. It fails afterwards, as a diagnostic message negative acknowledgement: 0x03 for a target not connected by configuration to your activated source address, 0x06 for a target this activation did not enable.

Protocol version and inverse version byte mismatch

Byte 0 is the version, byte 1 its bitwise inverse, and a bad pair gets NACK code 0x00 with the socket closed before any activation logic runs. The version also changes the layout: the Wireshark dissector reads the activation type as two bytes for 2010 and one byte for 2012 and 2019.

Sockets already registered, or a stale connection

Codes 0x01 and 0x03, both mediated by alive checks. An entity status request gives you the numbers before you start guessing.

Activation type mismatch, including the OEM payload

Code 0x06, including the case where the OEM-specific bytes the entity expects are missing because your client sent the 7-byte form.

Ordered diagnosis, discovery to a live session

Reaching this handshake from outside the vehicle, over a telematics path rather than a bench cable, changes the failure modes again, a case worked through in our telematics unit deep dive.

Step 1: does vehicle identification answer, and on which interface. Broadcast, capture, confirm which local interface the request left on. A laptop with a dock, a virtual adapter and a test NIC will send it out the wrong one and report silence. python-doipclient exposes client_ip_address so you can bind explicitly. No answer here means you never reached activation: check the interface, the link, and whether the entity’s external interface came up at all.

Step 2: does TCP connect and stay up. Connect to port 13400, or 3496 for the secured variant, and watch it. A socket that opens and closes about two seconds later with nothing sent is the initial inactivity timer: AUTOSAR resets a socket on which no routing activation request arrived within the configured initial inactivity time.

Step 3: read your own request, byte for byte. Before blaming the vehicle, decode what you sent. A default activation from tester 0x0E00 on protocol version 0x02, 11-byte form:

02 FD 00 05 00 00 00 0B 0E 00 00 00 00 00 00 00 00 00 00
|  |  |     |           |     |  |           |
|  |  |     |           |     |  |           OEM specific, 4 bytes
|  |  |     |           |     |  Reserved by ISO, 4 bytes
|  |  |     |           |     Activation type 0x00, default
|  |  |     |           Source address 0x0E00, the tester
|  |  |     Payload length 0x0000000B
|  |  Payload type 0x0005
|  Inverse protocol version 0xFD
Protocol version 0x02

The 7-byte form is the same without the trailing OEM field, length 0x00000007. Confirm the length field matches the bytes you actually sent: a mismatch is answered by a header NACK rather than an activation response, and the two look nothing alike in a capture.

Step 4: read the response code and jump to the matching row. Filter on doip.type == 0x0006 and read doip.response_code.

Step 5: confirm the session holds. An alive check response is legal to send unprompted and resets the entity’s inactivity timer, which makes it a cheap keepalive during a long sequence. Then send a real UDS request and confirm you get a response rather than a 0x8003.

Step 6: keep the evidence. Save the capture from identification through to the first successful diagnostic response. It is your reference trace for every later failure on that bench, and what a supplier will ask for when the answer is in the entity.

Traps on the tooling side

Library defaults that are not your vehicle’s values. python-doipclient defaults client_logical_address to 0x0E00, protocol_version to 0x02 while documenting that the implementation targets 0x03, and activation_type to Default. Scapy’s socket defaults source_address to 0xe80, doip_version to 2 and activation_type to 0, and auto-populates the target address from the entity logical address in a successful activation response, which is convenient until it sends requests somewhere you did not intend.

Functional addressing and naive response matching. Responses arrive from each ECU’s own address, and a client matching on the address pair drops them all.

Timeouts shorter than the vehicle’s. python-doipclient waits A_PROCESSING_TIME, 2 seconds, for the activation response. An entity running an authentication or confirmation callback can take longer than that.

Secured DoIP. 0x07 means the route requires TLS, and the secured port is 3496 in both python-doipclient and the Wireshark dissector. Note that AUTOSAR specifies 0x06, not 0x07, when a routing activation request on protocol version 0x02 arrives on an unsecured connection to activate a secured route, so the same misconfiguration can present as either code.

Firmware. Sometimes the answer is the ECU build, as the forum thread above showed. Reach that conclusion by elimination and with a capture in hand, not by assumption.

Tool error string to cause lookup

What the tool saysUnderlying conditionWhere to look
Numbered internal error after activate routingThe activation response was a denial, or malformedThe response code byte in the capture
Connection refused during client constructionThe library activated at construction and got anything other than 0x10, including 0x11The exception text, then the capture
Timed out waiting for routing activation responseNo response inside the client’s processing time, or a callback is runningWhether a 0x0006 exists in the capture
Connection reset shortly after connectInitial inactivity timer, or a denial with the socket closedWhether an activation request was sent, and whether a 0x0006 came back
No answers to a functionally addressed requestResponses arrived from physical source addresses and were filteredRaw capture, not library output
Malformed or undissected DoIP framesVersion or port mismatch in the dissectorHeader version byte, and Decode As for a non-default port

A healthy exchange, for comparison: an identification response, a TCP handshake, one 0x0005 request, one 0x0006 carrying 0x10, then 0x8001 traffic in both directions. Anything else is a story.

When activation succeeds and diagnostics still fail, check the diagnostic message acknowledgement next, then the UDS negative response, catalogued in our NRC table. Getting the layer right first is most of the work, and the boundaries are drawn in OBD2 vs DoIP vs UDS and the UDS explainer.

Where GSAS fits

Many routing activation tickets are configuration questions wearing a network problem’s clothes, and they resolve quickly once someone reads the response code and works backwards through the check order. The harder ones are the bench itself: which interface to connect to, whether the entity’s external interface has come up, which tester address the programme allows, and whether the capture decodes.

GSAS Micro Systems works as an engineering partner to diagnostics, HIL and validation teams across India, with applications engineers in Bengaluru, Pune, Chennai and Hyderabad who have worked through these benches. We would rather review a capture with you than hand you a checklist.

If you are specifying a diagnostics bench, or stuck on a session that stops at activation, see our automotive Ethernet capabilities or request a consultation.

References

  • AUTOSAR Classic Platform R24-11, Specification of Diagnostic over IP (AUTOSAR_CP_SWS_DiagnosticOverIP): payload layouts, the ordered checks and their codes, socket close behaviour, inactivity timers, DoIPRoutingActivationNumber, diagnostic message negative acknowledgement codes. autosar.org/standards/classic-platform
  • Wireshark DoIP dissector source packet-doip.c: response code and activation type value strings, payload type and header version lists, filter field names. gitlab.com/wireshark/wireshark
  • python-doipclient documentation and source: enumerations, address ranges, defaults, entity status fields, timing constants. python-doipclient.readthedocs.io, github.com/jacobschaer/python-doipclient
  • Scapy automotive DoIP contrib module: an independent copy of the same value maps, its socket defaults, its TLS fallback on 0x07. github.com/secdev/scapy
  • Scapy issue 4547: functionally addressed responses arriving from physical source addresses and being filtered out. github.com/secdev/scapy/issues/4547
  • Wireshark User’s Guide, Decode As, for DoIP on a non-default port. wireshark.org
  • Public forum thread on a tool vendor’s community site, “DoIP Undefined Error -8305 Activate Routing”: the generic-error symptom, the tester-side checks suggested, and the reporter’s closing note that a Wireshark trace resolved it and the cause was a bug in the ECU. forums.ni.com

Building for Automotive & Mobility?

Talk to our application engineers for personalized tool recommendations.

Frequently asked questions

What does a DoIP routing activation response code actually tell me?
It tells you which check inside the entity failed, and the checks are ordered. The Wireshark DoIP dissector, the Scapy DoIP contrib module and the python-doipclient library all carry the same denial and success codes: 0x00 unknown source address, 0x01 all concurrently supported TCP_DATA sockets registered and active, 0x02 a source address different from the table connection entry on an already activated socket, 0x03 the source address already registered and active on a different socket, 0x04 missing authentication, 0x05 rejected confirmation, 0x06 unsupported routing activation type, 0x07 a request for an encrypted connection via TLS, 0x10 routing successfully activated, 0x11 routing will be activated with confirmation required. Wireshark and Scapy additionally mark 0x08 to 0x0F reserved by ISO 13400; python-doipclient's enumeration omits that range.
Why does the ECU reject my tester's source address?
Because the entity accepts only source addresses it has been configured to expect. The AUTOSAR Classic Platform specification of Diagnostic over IP states that if a routing activation request carries a source address that does not match a configured DoIPTesterSA, the entity sends response code 0x00 and closes the socket connection. There is no negotiation step and no discovery step for this value: it is configuration on the vehicle side, and the correct value comes from the OEM or supplier diagnostic specification for that programme.
What is the difference between the DoIP entity address and the tester logical address?
They are two different fields in two different directions. The tester logical address identifies your client and goes in the source address field of the routing activation request. The entity logical address identifies the ECU or gateway and comes back in the response: the AUTOSAR specification sets that field to the entity's configured DoIPLogicalAddress. python-doipclient documents the tester range as 0x0E00 to 0x0FFF and the ECU range as 0x0001 to 0x0DFF, and defaults its own client_logical_address to 0x0E00. Neither has any relationship to an IP address.
Why did routing activation work yesterday and fail today with all sockets registered?
Because the entity has a finite number of tester sockets and reclaims them when a tester fails to answer an alive check or when a socket goes idle past the configured general inactivity time. In the AUTOSAR specification, when the number of registered connections has reached the configured DoIPMaxTesterConnections, the entity sends an alive check request to every registered connection. If all of them answer within DoIPAliveCheckResponseTimeout, your request is denied with 0x01. If at least one times out, that connection is closed and yours proceeds. So 0x01 usually means another live tester holds the socket, not that a stale one does.
Do I need routing activation before every diagnostic request, or once per connection?
Once per TCP connection, and then keep the connection busy. The AUTOSAR specification says diagnostic messages are evaluated only in the ISO 13400 connection state Registered [Routing Active], and that a diagnostic message received on a socket not in that state is silently discarded. The same document specifies an inactivity timer that is reset on every send or receive after activation, and a socket reset once it reaches the configured general inactivity time. python-doipclient's constants put the general figure at 300 seconds and the initial one at 2 seconds. Reconnecting means activating again.
Why do responses come back from a physical address when I addressed functionally?
Because each ECU answers from its own address. A public issue filed against the Scapy packet library in October 2024 reports exactly this: with a functionally addressed request, the source addresses of the responses differ from the target address of the request, and Scapy's response matching filtered them out, so the call returned no answers at all. The reporter worked around it by patching the matching function to ignore the address pair, and Scapy has since changed its matching so it no longer keys on the addresses (issue closed November 2024). The lesson generalises to any client that matches strictly on the address pair, where functional addressing looks like silence even though the ECUs replied.
My vehicle identification request gets no reply, is that already a routing activation problem?
No, it is a layer below. Vehicle identification is a UDP exchange and routing activation is a TCP one, and a failure at the UDP stage means you never reached the handshake. Check which interface the broadcast left on, whether the entity's externally facing interface is up at all, and whether you are inside the announcement window. The AUTOSAR specification models a DoIP interface that is activation-line controlled and establishes its connections when the activation line status switches to active, so an entity can be perfectly healthy and still answer nothing until that line is asserted.
Routing activation succeeded but my UDS request times out, what changed?
Nothing about activation. Routing activation admits your socket and enables routing to the target addresses configured for that activation, and nothing more. The AUTOSAR specification defines a separate diagnostic message negative acknowledgement, payload type 0x8003, whose code 0x03 is sent when the target address is not connected by configuration to the tester source address you activated with, and whose code 0x06 is sent when the target address was not activated by the routing activation. Those are transport refusals. A response that starts with 0x7F is a UDS negative response, which means the ECU understood you and declined, and belongs to a different table.

Stay in the Loop

Get monthly compliance updates, product insights, and engineering best practices delivered to your inbox.

Related Articles

Master and slave roles on a 100BASE-T1 link: the master PHY times its transmitter from a local clock, the slave recovers the clock from the received signal, with the both-master and both-slave misconfigurations that leave the link down, from GSAS Micro Systems India
Automotive Ethernet Automotive & Mobility

100BASE-T1 Link Won't Come Up: A Vendor-Neutral Checklist

A 100BASE-T1 link that will not come up is almost never a mystery, but the answers on the web are written per silicon vendor and do not transfer. This is the ordered bring-up checklist that holds regardless of which PHY, switch or SoC you have: physical layer first, then the PHY over MDIO, then the master and slave pairing, then the causes of a link that comes up and drops. The standards and tooling claims trace to IEEE 802.3 task force records, the Linux ethtool and kernel documentation or published test material. Written by the GSAS Micro Systems engineering team in India.

29 Aug 2026 · 14 min read
Five-step master and slave decision flow for a 100BASE-T1 media converter: read the ECU port role, set the converter to the complement, match the speed, check the wiring, link up, from GSAS Micro Systems India
Automotive Ethernet Automotive & Mobility

100BASE-T1 Media Converters: How to Choose One

Search for a 100BASE-T1 media converter and you get SKU pages that document their own DIP switches, plus a pile of copper-to-fibre converters that have nothing to do with single-pair automotive Ethernet. This is the selection guide neither publishes: what the box does at the PHY layer, when a converter is the wrong box, and the nine criteria that decide fitness, each written as a question to put to the supplier rather than a specification we invented. Standards claims trace to IEEE 802.3 task force records and the public OPEN Alliance specifications. Written by the GSAS Micro Systems engineering team in India.

29 Aug 2026 · 13 min read
Side by side comparison of a 10BASE-T1S multidrop mixing segment, one balanced pair with four nodes on short stubs and a termination at each end, against a point to point star of four separate links into switch ports, from GSAS Micro Systems India
Automotive Ethernet Automotive & Mobility

10BASE-T1S and PLCA: Multidrop Ethernet Explained

10BASE-T1S is the one member of the T1 single-pair Ethernet family that keeps a shared medium, and PLCA is the reconciliation sublayer that stops the nodes on it from colliding. This article covers what IEEE 802.3cg standardises, how the beacon and transmit opportunities schedule a cycle, the node count and segment length figures the OPEN Alliance interoperability test suite works to, and the failure modes that put a segment quietly back into contention while every link still looks up. Written by the GSAS Micro Systems engineering team in India for teams bringing up multidrop segments on the bench.

29 Aug 2026 · 12 min read