In short
OBD2, UDS and DoIP are not three competing vehicle diagnostics protocols. OBD2 is the regulated emissions diagnostic scope reached through the standard 16-pin connector, UDS (ISO 14229) is the manufacturer service layer that sits alongside it at the same application layer, and DoIP (ISO 13400) is one transport that carries UDS over automotive Ethernet instead of CAN.
A job spec asks for OBD2, UDS and DoIP. A tool menu offers all three. A colleague uses them in one sentence as though they were three versions of the same thing. They are not, and the comparison feels hard because the three come from different shelves.
These three vehicle diagnostics protocols sit at different heights in one stack. OBD2 is a regulated scope of data, UDS is a service layer, DoIP is a transport. Once the layering is clear, “OBD2 vs UDS” and “DoIP vs UDS” stop being comparisons and become directions.
Every fact below comes from a public source listed at the end. ISO 14229 and ISO 13400 are paid documents, so nothing here quotes them.
The short answer
OBD2 is a regulated scope. A small set of emissions related data a vehicle must expose to any generic tester, through a standard connector, using standard identifiers. The same request means the same thing on any compliant vehicle.
UDS is a service layer. How a tester and an ECU hold a diagnostic conversation: sessions, security access, routines, data identifiers, fault memory, resets. Far richer than the emissions set, and manufacturer territory at the data level.
DoIP is a transport. It carries diagnostic payloads over an IP network, and has nothing to say about what those payloads mean.
The layering, in one block
APPLICATION OBD2 generic scope Manufacturer diagnostics
(SAE J1979 PIDs, (UDS services, ISO 14229)
services 01 to 0A)
TRANSPORT ISO-TP over CAN | ISO-TP over CAN FD | DoIP over Ethernet
(ISO 15765-2) (up to 64 byte frames) (ISO 13400)
PHYSICAL 16-pin J1962 connector: CAN on pins 6 and 14,
Ethernet pairs on manufacturer discretion pins
The py-uds OSI model page shows the same shape: ISO 14229-1 at the application layer and ISO 14229-2 at the session layer, with CAN, FlexRay, Ethernet, K-Line and LIN beneath as transport and physical layers, and ISO 13400-2 named as the Ethernet transport.
The sentence to remember
OBD2 is what you are allowed to see, UDS is how you ask, and DoIP is the road the question travels on. A modern vehicle uses all three at once, in those three roles.
OBD2: what the regulation actually requires
Emissions scope, one connector, standard parameter IDs
People search for the OBD2 protocol as though it were one protocol. It is not: it is a regulated data scope, carried over whichever signalling the vehicle uses.
Wikipedia’s on-board diagnostics article records that CARB issued the OBD-II specification and mandated it for all cars sold in California from model year 1996. Also from 1996 it was made mandatory across the United States for passenger cars and petrol powered light trucks under 8,500 lb (3,900 kg) gross vehicle weight rating. Since 2008, cars sold there are required to use ISO 15765-4 signalling, a variant of CAN. The access point is the female 16-pin J1962 connector, type A for 12 volt vehicles and type B for 24 volt vehicles.
Inside that scope the data set is standardised. The public OBD-II PID page describes PIDs as codes used to request data from a vehicle, and names SAE J1979 as the standard defining many of them. The generic services:
| Service | What it returns |
|---|---|
| 01 | Show current data |
| 02 | Show freeze frame data |
| 03 | Show stored Diagnostic Trouble Codes |
| 04 | Clear Diagnostic Trouble Codes and stored values |
| 05 | Test results, oxygen sensor monitoring (non CAN only) |
| 06 | Test results, other component or system monitoring |
| 07 | Show pending Diagnostic Trouble Codes |
| 08 | Control operation of on-board component or system |
| 09 | Request vehicle information |
| 0A | Permanent Diagnostic Trouble Codes |
Within service 01 the identifiers are fixed and public: 0x0C is engine speed, 0 to 16,383.75 rpm; 0x0D is vehicle speed, 0 to 255 km/h; 0x05 is engine coolant temperature, minus 40 to 215 degrees Celsius. That fixity is the point: any compliant tester can ask any compliant vehicle for engine speed and get engine speed.
Why a scan tool sees so little of a modern vehicle
Because the scope was drawn around emissions, not around the vehicle. Seat memory, ADAS calibration, battery pack cell voltages, gateway routing state, per-ECU software part numbers: none of that is in the generic set. The same public page says so from the other direction: manufacturers may define additional services above 09, naming service 22 as defined by SAE J2190 for Ford and GM, and service 21 for Toyota. Past the generic set you are in manufacturer territory, and that is where UDS lives.
UDS: the manufacturer service layer
What UDS adds beyond emissions data
UDS gives you a stateful conversation rather than a data tap. The udsoncan documentation lays out the services an engineer works with: DiagnosticSessionControl (0x10) to move the ECU into a session where more is permitted, SecurityAccess (0x27) to unlock gated functions with a seed and key exchange, ReadDataByIdentifier (0x22) and WriteDataByIdentifier (0x2E) for identifiers, RoutineControl (0x31) for routines, ReadDTCInformation (0x19) for fault memory, and ECUReset (0x11).
The message shape is small. The py-uds knowledge base gives it plainly: a request is identified by its service identifier, a positive response uses RSID = SID + 0x40, and a refusal arrives under the negative response service identifier 0x7F with a reason code. Our UDS protocol explainer covers sessions and security access, our UDS services list covers the service IDs one by one, and our UDS negative response code table covers the refusals.
Here is the asymmetry that resolves the OBD2 versus UDS question. OBD2 standardises the data. UDS standardises the conversation. Two ECUs from two OEMs both answer a well formed ReadDataByIdentifier request in the same format, while the identifier you have to send, and the meaning of the bytes that come back, are OEM defined and generally unpublished. A UDS request is portable. UDS knowledge of a specific vehicle is not.
Why the same connector carries both
The public J1962 pinout is a good map. Pins 6 and 14 are CAN high and CAN low, cited to ISO 15765-4 and SAE J2284. Several pins are left to manufacturer discretion, and the uses noted there include Ethernet TX+, TX-, RX+ and RX- on pins 3, 11, 12 and 13, with “Activate Ethernet” among the noted uses of pin 8, on certain vehicles.
Some vehicles expose diagnostics over both CAN and Ethernet through the same connector, with the Ethernet side on pins the standard leaves to the manufacturer. Which conversation an ECU answers depends on the diagnostic address and the service identifier the request carries. The pins determine which network you are on, but they do not determine whether the exchange is generic emissions data or manufacturer UDS, since either can travel on either path.
OBDonUDS, the direction of travel
The two worlds are converging. SAE lists a standard in its catalogue as J1979-2, titled “E/E Diagnostic Test Modes: OBDonUDS”, which rebuilds the regulated emissions data set on the UDS service model rather than the older generic modes. It is a paid document, so this page names it and quotes nothing from it.
The transports: CAN, CAN FD and DoIP
CAN with ISO-TP: the classic path
A Classical CAN frame carries at most eight bytes of payload, which the Linux kernel SocketCAN documentation gives as a length ranging from 0 to 8. A UDS response is routinely longer, so a transport layer has to cut it up. That is ISO-TP, and the can-isotp documentation describes the mechanics: a single frame when the payload fits, otherwise a first frame followed by consecutive frames, with the receiver sending flow control messages to pace the sender. Two parameters matter: blocksize, the frames sent before flow control is expected, default 8, and stmin, the separation time between frames, default 0.
CAN FD: what actually changed
CAN FD is a bus generation, not a diagnostic protocol. The kernel documentation describes CAN FD capable controllers as supporting up to 64 bytes of payload and two different bitrates, one for the arbitration phase and one for the payload phase, with the data phase bitrate required to be at least the arbitration bitrate. can-isotp exposes this through a can_fd parameter and a tx_data_length whose valid values are 8, 12, 16, 20, 24, 32, 48 and 64.
That answers the query pairing the two terms. “What is DoIP and CAN FD” is really two answers: CAN FD widened the old road, DoIP is a different road. A 64 byte frame means fewer consecutive frames for the same response, and the UDS request you send is byte for byte identical either way.
DoIP over automotive Ethernet
DoIP moves diagnostics onto the vehicle’s IP network. The python-doipclient documentation describes a client for communicating with modern ECUs over automotive Ethernet, and gives the surface: TCP port 13400, or 3496 with TLS, and UDP 13400 for discovery. Entities are addressed by logical address, the ranges given as 0x0001 to 0x0DFF for ECUs and 0x0E00 to 0x0FFF for clients, default 3584. A vehicle announces itself on power up, or you ask with a vehicle identification request. Before anything diagnostic happens there is routing activation: “Most ECU’s require an activation request before they’ll respond.”
Our DoIP explainer covers the message types and failure modes, our automotive Ethernet guide covers the network underneath, and our automotive Ethernet capabilities page describes the bench work we do, and our note on the shift to Ethernet based vehicle communication places this transport in the wider vehicle architecture.
Changing the transport does not change the request
The open source stack demonstrates this rather than asserting it. The udsoncan documentation states its own scope directly: “This project does not implement any communication protocol below the UDS layer, but provides a standard interface to interact with them.” It offers interchangeable connection objects, including PythonIsoTpConnection, IsoTPSocketConnection, SocketConnection and J2534Connection, and lets you write your own by inheriting BaseConnection. python-doipclient supplies exactly that: a DoIPClientUDSConnector presenting a DoIP link to the same udsoncan client.
The same ReadDataByIdentifier call, unchanged, therefore reaches the ECU over ISO-TP on CAN, over ISO-TP on CAN FD, or over DoIP. The service layer does not know or care which.
OBD2, UDS and DoIP side by side
| OBD2 | UDS | DoIP | |
|---|---|---|---|
| What layer it is | Application scope, a defined subset of data | Application service layer | Transport |
| Named by | SAE J1979 for the PIDs, SAE J1962 for the connector | ISO 14229 | ISO 13400 |
| Who requires it | Emissions regulators, such as CARB | The vehicle manufacturer | Nobody mandates it; it is an architecture choice |
| Scope of data | Emissions related, fixed and public | Whatever the ECU implements, OEM defined | No data scope; it carries payloads |
| How data is named | Standard PIDs, same meaning everywhere | Data identifiers, meaning set by the OEM | Not applicable; addressing is by logical address |
| Typical transport | CAN, on ISO 15765-4 signalling in the US since 2008 | CAN, CAN FD, DoIP and others | TCP and UDP over automotive Ethernet |
| Typical tool | Generic handheld or dongle | OEM or engineering diagnostic tool | The tool underneath, not a separate tool |
| Where you meet it | Emissions test, warning light, fleet telematics | Development, validation, production, service | Modern vehicles and Ethernet benches |
Decoding the phrases people actually search
| The phrase | What is actually going on |
|---|---|
| ”UDS over CAN FD” | The UDS service layer, segmented by ISO-TP, over a CAN FD bus with frames up to 64 bytes |
| ”DoIP diagnostics” | UDS services carried over TCP or UDP on the vehicle’s Ethernet, after routing activation |
| ”OBD2 scanner” | A tool speaking the generic emissions services, usually over CAN on pins 6 and 14 |
| ”DoIP vs UDS” | Not a versus. One is the road, the other is the conversation held on it |
| ”OBDonUDS” | The regulated emissions data set expressed in UDS services rather than the older generic modes |
Which one am I actually talking to?
By connector. Pin usage tells you a lot before you send a byte. Activity on pins 6 and 14 is CAN. A tool wanting an IP address or logical address rather than a CAN identifier is on the Ethernet side.
By traffic. On CAN, look at the identifier pair and the ISO-TP framing: a first frame followed by consecutive frames means a payload larger than one frame, which is a UDS sized answer rather than a generic PID. On an Ethernet bench, filter TCP port 13400 first, because diagnostic traffic shares the link with everything else, including SOME/IP service traffic. Wireshark publishes a UDS display filter reference for the layer above.
By failure mode. A generic request returning nothing usually means the vehicle does not implement that service, or you are on the wrong pins. A three byte reply beginning 0x7F is a refusal carrying a reason code, and the generic emissions services use the same shape, so read the second byte: 0x7F 0x01 is a refused generic request, while 0x7F 0x22 or 0x7F 0x27 puts you in UDS territory. Take the reason code to our UDS negative response code table. Silence on an Ethernet bench before a single UDS byte is exchanged usually means routing activation, which belongs in the DoIP explainer.
What this means for two different readers
A workshop or fleet team
A generic tool reaches the generic scope, and that scope is useful: stored, pending and permanent fault codes, freeze frame, live emissions parameters, vehicle information. It will not reach the OEM data set, because the identifiers are unpublished and anything past a plain read normally sits behind the security access service. That is a design decision, not a limitation of your tool.
An R&D, HIL or validation team
A bench needs the service layer and a real transport, because the work is sessions, routines, identifiers and fault injection rather than emissions readouts: a transport you can configure and capture, ISO-TP parameters you set rather than guess, and an addressing and activation setup matching the vehicle. Where that entry point sits is also moving as vehicles consolidate onto domain and zone controllers, which our note on domain and zone controller programming describes. Production reflash over the Ethernet path is a separate discipline with its own tooling, covered in our note on Ethernet connected production tooling.
Where GSAS fits
This confusion gets expensive at one moment: when a team specifies a bench for the wrong layer. An emissions scoped tool cannot validate a manufacturer service, and a CAN only setup cannot reproduce a vehicle whose tester arrives over IP.
GSAS Micro Systems is an engineering partner to ECU, HIL and validation teams. We consult on which layer a problem lives on, and on what a bench needs to reach it: the transport your architecture requires, what to capture when a request fails, and how the diagnostic path should be built. Our engineers work IST hours and quotations are issued in INR.
If you are planning diagnostic or Ethernet bring-up work, start with our automotive Ethernet capabilities, or send us the architecture and the problem through a request for quote and we will come back with what we would use and why.
References
- Wikipedia, On-board diagnostics, for regulatory history and the J1962 pinout: en.wikipedia.org/wiki/On-board_diagnostics
- Wikipedia, OBD-II PIDs, for the generic services and parameter IDs: en.wikipedia.org/wiki/OBD-II_PIDs
- udsoncan documentation, service set and client: udsoncan.readthedocs.io
- udsoncan documentation, connection objects: udsoncan.readthedocs.io/en/latest/udsoncan/connection.html
- py-uds knowledge base, UDS OSI model: uds.readthedocs.io/en/stable/pages/knowledge_base/osi_model.html
- py-uds knowledge base, diagnostic message structure: uds.readthedocs.io/en/stable/pages/knowledge_base/diagnostic_message.html
- python-doipclient documentation, ports and routing activation: python-doipclient.readthedocs.io
- Linux kernel SocketCAN documentation, CAN and CAN FD payloads and bitrates: docs.kernel.org/networking/can.html
- can-isotp documentation, segmentation, blocksize, stmin and frame lengths: can-isotp.readthedocs.io
- SAE International catalogue listing for J1979-2, OBDonUDS (title only): sae.org/standards/content/j1979-2
- Wireshark UDS display filter reference: wireshark.org/docs/dfref/u/uds.html
Also appears in:
Building for Automotive & Mobility?
Talk to our application engineers for personalized tool recommendations.
You might also like
View all →