In short
UDS services are identified by a one byte service ID, running from 0x10 DiagnosticSessionControl to 0x87 LinkControl. The public udsoncan reference documents twenty three of them in working form. A positive reply is the request service ID plus 0x40, and a failure is the three byte negative response 0x7F, service ID, negative response code.
This is the lookup page for UDS services: one table of UDS service identifiers, every row taken from the public udsoncan reference documentation rather than from a paid standard, with what each service does and the session it usually needs. Below it, byte level detail on the five services that carry most of the traffic on a real bench: 0x27, 0x22, 0x2E, 0x19 and 0x31.
The concepts sit in the companion article: what a session is, what security access actually protects, and how the request and response pair works. If any of that is new, read UDS explained: ISO 14229 services, sessions and security access first. For the network underneath, see our complete guide to automotive Ethernet and our automotive Ethernet capabilities page.
How to read this table
Service ID, sub-function and parameters
Every UDS request begins with one byte, the service identifier. Many services follow it with a sub-function byte, then with service specific parameters. The udsoncan request builder assembles payloads in exactly that order.
Bit 7 of the sub-function byte is not part of its value. udsoncan sets it by combining the sub-function with 0x80 when suppress positive response is requested. That is why 3E 00 expects an answer and 3E 80 does not, and why a sub-function read out of a capture should be masked before you look it up.
The positive response rule and the negative response shape
A positive response uses the request service identifier plus 0x40. The python-uds knowledge base states the rule as RSID = SID + 0x40, so 0x22 answers as 0x62, 0x27 as 0x67 and 0x31 as 0x71.
A failure looks nothing like that. It is three bytes: 0x7F, the echoed request service identifier, and a negative response code. The udsoncan response parser checks the first byte against 0x7F, then reads the service from the second byte and the error code from the third. What each code means is in our UDS negative response code table.
Supported in the standard versus implemented in your ECU
Treat the session column below as a map, not a promise. The udsoncan introduction is explicit that UDS defines the list of available services only for the default session, and that manufacturers determine what is available in the others. It also notes that a client may switch sessions without restriction, so a session change is a mode selector rather than a security mechanism.
Only the OEM diagnostic specification for your ECU is therefore authoritative, and a reference implementation’s list is a superset of what any single ECU answers.
The UDS service ID table
The columns are the identifier, the service name, what it does, and the session convention; where security access is normally needed first, the session column says so. Byte level examples for the five highest traffic services follow below the table.
| SID | Service name | What it does | Typical session |
|---|---|---|---|
| 0x10 | DiagnosticSessionControl | Moves the server into a named session. udsoncan defines defaultSession 1, programmingSession 2, extendedDiagnosticSession 3, safetySystemDiagnosticSession 4 | Any, this is how you leave the default one |
| 0x11 | ECUReset | Restarts the server. udsoncan reset types: hardReset 1, keyOffOnReset 2, softReset 3, enableRapidPowerShutDown 4, disableRapidPowerShutDown 5 | Extended or other non-default |
| 0x14 | ClearDiagnosticInformation | Clears stored fault memory for a three byte group mask, 0 to 0xFFFFFF, where 0xFFFFFF means all | Default or extended |
| 0x19 | ReadDTCInformation | Reads fault memory. The sub-function selects the report; udsoncan defines twenty nine of them | Default or extended |
| 0x22 | ReadDataByIdentifier | Reads one or more two byte data identifiers, packed big endian | Default for public identifiers, non-default for the rest |
| 0x23 | ReadMemoryByAddress | Reads a raw memory block described by an address and a length | Non-default, usually security unlocked |
| 0x27 | SecurityAccess | Seed and key handshake that sets a security level flag in the server | Non-default |
| 0x28 | CommunicationControl | Enables or disables normal transmit and receive; udsoncan control types: enableRxAndTx 0, enableRxAndDisableTx 1, disableRxAndEnableTx 2, disableRxAndTx 3, enableRxAndDisableTxWithEnhancedAddressInformation 4, enableRxAndTxWithEnhancedAddressInformation 5 | Extended or other non-default |
| 0x29 | Authentication | Authentication exchange; udsoncan exposes authentication task values 0 to 8 | Non-default |
| 0x2C | DynamicallyDefineDataIdentifier | Builds a composite identifier: defineByIdentifier, defineByMemoryAddress, clearDynamicallyDefinedDataIdentifier | Extended or other non-default |
| 0x2E | WriteDataByIdentifier | Writes a value to one two byte identifier; the response echoes the identifier | Non-default, usually security unlocked |
| 0x2F | InputOutputControlByIdentifier | Takes control of an input or output bound to an identifier, with control parameter, values and masks | Extended or other non-default |
| 0x31 | RoutineControl | Starts, stops or fetches results for a two byte routine: startRoutine 1, stopRoutine 2, requestRoutineResults 3 | Extended or other non-default |
| 0x34 | RequestDownload | Announces a bulk transfer into the server, with a data format identifier and a memory location | Non-default, security unlocked |
| 0x35 | RequestUpload | The same announcement in the other direction, server to client | Non-default, security unlocked |
| 0x36 | TransferData | Carries one block, prefixed by a one byte sequence number, 0 to 0xFF | Follows an accepted 0x34 or 0x35 |
| 0x37 | RequestTransferExit | Ends the transfer, with optional trailing data | Follows the last 0x36 |
| 0x38 | RequestFileTransfer | File oriented transfer; udsoncan parameters are mode of operation, path, data format identifier and file size | Non-default, security unlocked |
| 0x3D | WriteMemoryByAddress | Writes a raw memory block described by an address and a length | Non-default, security unlocked |
| 0x3E | TesterPresent | Keeps a non-default session alive; the sub-function is always 0 | Any |
| 0x83 | AccessTimingParameter | Reads or sets timing parameters; udsoncan access types: read extended 1, reset to default 2, read active 3, set 4 | Extended or other non-default |
| 0x85 | ControlDTCSetting | Turns fault recording on or off while you deliberately disturb the ECU | Extended or other non-default |
| 0x87 | LinkControl | Prepares and then executes a change of bus rate | Non-default |
Four more identifiers appear in the udsoncan list but are marked not implemented: 0x24 ReadScalingDataByIdentifier, 0x2A ReadDataByPeriodicIdentifier, 0x84 SecuredDataTransmission and 0x86 ResponseOnEvent.
Service 0x27 SecurityAccess in detail
Odd asks, even answers
The sub-function of 0x27 is the security level, and its least significant bit is a flag rather than part of the number. udsoncan documents the level as running from 1 to 0x7E, with the bit set meaning request seed and clear meaning send key. Its client exposes this as request_seed on an odd level and send_key on the next even one, correcting the bit if you pass the wrong parity.
So the levels come in pairs: level 1 and level 2 are one lock, level 3 and level 4 the next. udsoncan describes up to sixty four levels, each a boolean flag in the server, though the sub-function range it enforces, 1 to 0x7E, gives sixty three usable pairs in practice. What each flag unlocks is left to the manufacturer: a whole service, a single sub-function, or access to one identifier.
A byte level exchange
27 01 request seed for level 1
67 01 <seed bytes> positive response, seed for that level
27 02 <key bytes> send the key computed from the seed
67 02 positive response, level unlocked
The middle step is the one no public document can give you. udsoncan says the seed is usually a random value and that the client must compute the key with an algorithm defined by the ECU manufacturer, adding that the algorithm can be any algorithm.
A wrong key, too many attempts, or a delay the server is still enforcing all come back as negative responses rather than seeds: 0x33 securityAccessDenied, 0x35 invalidKey, 0x36 exceedNumberOfAttempts and 0x37 requiredTimeDelayNotExpired. Those four are decoded in our negative response code table.
Reading and writing data: 0x22 and 0x2E
Both services address data by a two byte identifier, packed big endian. udsoncan builds a read request by packing each identifier as a big endian unsigned short, so asking for two is the service byte plus four bytes.
22 F1 90 read one identifier
62 F1 90 ... echoed identifier, then its value
22 F1 90 F1 8C read two identifiers in one request
The response is why a read is less trivial than it looks. udsoncan parses it as a repeating pattern of echoed identifier then value, and needs a codec configuration to know how many bytes each value occupies, because nothing in the response marks where one value ends and the next identifier begins. Ask for several at once and you must know their lengths in advance, or parse only the first.
Writing is the mirror image:
2E F1 90 <new value bytes>
6E F1 90
udsoncan interprets the write response by unpacking the first two bytes as the echoed identifier, the only field it extracts. A thin positive response is therefore normal. Confirm a write by reading the identifier back, not by inspecting the acknowledgement.
Reading fault memory: 0x19 and 0x14
0x19 is a family of reports behind one service identifier. udsoncan defines twenty nine sub-functions, from reportNumberOfDTCByStatusMask as 1 and reportDTCByStatusMask as 2, through reportDTCSnapshotRecordByDTCNumber as 4, reportDTCExtendedDataRecordByDTCNumber as 6 and reportSupportedDTCs as 0x0A, to reportWWHOBDDTCWithPermanentStatus as 0x55 and reportDTCInformationByDTCReadinessGroupIdentifier as 0x56. Most bench work uses four: count by mask, list by mask, snapshot by fault number, and extended data by fault number.
19 02 FF list DTCs matching a status mask of 0xFF
59 02 ... status availability mask, then the records
The response begins with a status availability mask and continues with the matching records, which udsoncan decodes into its own DTC objects. Read the mask first: it says which status bits the ECU maintains at all, and a bit it does not maintain never gets set however the part behaves.
Clearing is 0x14, which takes a three byte group mask. udsoncan validates it over 0 to 0xFFFFFF, defaults to 0xFFFFFF meaning all faults, and packs it high byte first.
14 FF FF FF clear all groups
54 positive response
An optional trailing memory selection byte exists, but udsoncan refuses to build it unless the client is configured for the 2020 edition of the standard, so send the three byte form unless the OEM specification says otherwise.
RoutineControl 0x31
0x31 runs a procedure rather than moving data. The udsoncan examples use it as their canonical raw payload, 31 01 12 34, meaning start the routine with identifier 0x1234.
31 01 12 34 start routine 0x1234
71 01 12 34 <status> echo of sub-function and routine, then status record
31 03 12 34 request results for the same routine
The response is fixed at the front and open at the back. udsoncan requires at least three data bytes, reads the first as the echoed sub-function and the next two as the echoed routine identifier, and treats the rest as a routine status record whose meaning is OEM defined.
Two habits save time. Echo check every response, since a positive answer carrying the wrong routine identifier means your request was built wrong, not that the routine passed. And expect a long routine to answer with a pending negative response first: that is the server asking for more time.
Data transfer services 0x34 to 0x38
These five move bulk data. 0x34 announces a transfer into the server and 0x35 one out of it; udsoncan builds both as the service byte, a data format identifier, an address and length format identifier, then address and size bytes. 0x36 carries the blocks, 0x37 closes the transfer, 0x38 does the same job in file terms. In practice they answer only once 0x10 has selected the programmingSession and 0x27 has unlocked the matching level, but as always the OEM specification settles it.
The value that decides everything downstream comes back in the 0x34 response. udsoncan reads the high nibble of the first response byte as a length format identifier, saying how many following bytes hold the maximum block length, and rejects a nibble above 8. Read that number rather than assuming one. Since udsoncan builds each 0x36 as the service byte, a one byte sequence number and then the data, your payload must fit inside the announced block together with those two bytes.
udsoncan validates the sequence number over 0 to 0xFF. On the wire the counter starts at 0x01 for the first block after an accepted 0x34 or 0x35 and rolls over from 0xFF to 0x00 rather than growing. The response echoes it back, so a mismatch is a resynchronisation problem, not a data problem.
Running this group on a production line, in seconds and against many units at once, is a different engineering problem from running it once on a bench, and we cover it separately in our note on ECU data transfer over automotive Ethernet in production.
OEM specific identifiers and the paid standard
Telling an OEM service from a standard one
If you meet a service identifier that is not in the table above and the ECU answers it with that identifier plus 0x40 rather than 0x7F, you are looking at a manufacturer or supplier defined service. The arithmetic rule holds even for services no public library knows, and reference implementations expect this: the first usage level in the udsoncan examples sends raw bytes and waits for a frame, with no service object involved.
One naming trap: a service in UDS is a type of diagnostic request, while a service in the service oriented sense, discoverable and subscribable, belongs to the middleware layer, which we cover in SOME/IP explained.
If you came here looking for the ISO 14229 PDF
Say it plainly: there is no free official copy. ISO 14229-1 is sold through the ISO catalogue at iso.org, and only the front matter is published openly, typically the foreword, introduction, scope, normative references and terms and definitions. Anything offering the full text at no cost is not a legitimate source, and we do not reproduce its clauses, tables or figures here.
What is genuinely public covers most day to day work, and each source is listed below: udsoncan for a service by service reference, the python-uds knowledge base for message structure, the Scapy automotive layer for the same services as packet classes, the Wireshark display filter reference for field names, and the AUTOSAR Classic Platform diagnostic specifications for how a conforming stack implements them. The paid document remains the arbiter for anything you certify against, and there is no substitute for it there.
Where GSAS fits
The difficulty is rarely the table. It is turning an OEM diagnostic specification into a bench setup that answers, and then into a test sequence that runs the same way every time: which services the ECU really implements, which session and security level each needs, and what the routine status bytes mean.
GSAS Micro Systems is an engineering partner to teams doing that work in India. We consult on diagnostic bench architecture and test sequencing, our engineers work IST hours alongside yours, and we invoice in INR. If you are running diagnostics over Ethernet, our automotive Ethernet capabilities page covers what we do at that layer, and you can start a conversation here.
References
- udsoncan documentation, services, client API and examples: https://udsoncan.readthedocs.io/
- python-uds knowledge base, diagnostic message structure: https://uds.readthedocs.io/en/stable/pages/knowledge_base/diagnostic_message.html
- Scapy automotive layer: https://scapy.readthedocs.io/en/latest/layers/automotive.html
- Wireshark UDS display filter reference: https://www.wireshark.org/docs/dfref/u/uds.html
- AUTOSAR Classic Platform standards: https://www.autosar.org/standards/classic-platform
- ISO catalogue entry for ISO 14229-1:2020, paid document: https://www.iso.org/standard/72439.html
Also appears in:
Building for Automotive & Mobility?
Talk to our application engineers for personalized tool recommendations.
You might also like
View all →