# UDS Negative Response Codes erklärt für Tester

Was eine negative UDS-Antwort (0x7F) am Prüfstand verrät: der Aufbau, die Codes, die bei Enumeration und SecurityAccess zählen, und wie du sie liest.

Source: https://auto-st.com/de/insights/uds-negative-response-codes-erklaert · Updated: 2026-10-07

Eine negative UDS-Antwort ist das ECU, das dir sagt, dass es nicht tut, worum du gebeten hast, und warum. Die Antwort besteht immer aus drei Bytes: `7F`, dem Service-Identifier (SID) des abgelehnten Requests und einem Negative Response Code (NRC). Richtig gelesen bilden diese Codes das ECU für dich ab, denn ein ECU, das präzise ablehnt, beschreibt zugleich seine eigene Struktur, eine Antwort nach der anderen.

## Der Aufbau, Byte für Byte

Sende einen Request und du bekommst eines von drei Ergebnissen. Eine positive Antwort beginnt mit dem SID plus `0x40`: ein Request `22 F1 90` (ReadDataByIdentifier, DID 0xF190), beantwortet mit `62 F1 90 ...`, ist ein Erfolg. Eine negative Antwort sieht so aus:

```
7F 22 31
│  │  └─ NRC: requestOutOfRange
│  └──── abgelehnter SID: 0x22 ReadDataByIdentifier
└─────── Negative-Response-Service-Identifier
```

Das dritte Ergebnis ist Stille, die auf CAN meist bedeutet, dass der ISO-TP-Frame (ISO 15765-2) nie akzeptiert wurde, die Arbitration-ID falsch ist oder das ECU beschäftigt ist. Stille ist kein NRC, und du solltest sie anders behandeln als eine ausdrückliche Ablehnung.

## Die Codes mit dem meisten Informationsgehalt

ISO 14229-1 Anhang A definiert die volle Tabelle. Während eines Scans erledigt eine Handvoll Codes die meiste Arbeit:

| Code | ISO-Name | Was er dem Tester sagt |
| --- | --- | --- |
| `0x10` | generalReject | Das ECU lehnt ohne Grund ab. Manche Implementierungen antworten das auf alles Unverstandene, was Struktur verbirgt. |
| `0x11` | serviceNotSupported | Der Service existiert auf diesem ECU gar nicht. |
| `0x12` | subFunctionNotSupported | Der Service existiert, die Sub-Funktion nicht. |
| `0x13` | incorrectMessageLengthOrInvalidFormat | Länge oder Format falsch. Nützliches Signal beim Fuzzing. |
| `0x22` | conditionsNotCorrect | Der Service existiert, aber Vorbedingungen fehlen (falscher Zustand, Drehzahl, Spannung). |
| `0x31` | requestOutOfRange | Der Parameter, meist ein DID oder RID, ist unbekannt oder out of range. |
| `0x33` | securityAccessDenied | Der Service ist hinter SecurityAccess (0x27) gesperrt. |
| `0x35` | invalidKey | Falscher Key an SecurityAccess gesendet. |
| `0x36` | exceedNumberOfAttempts | Zu viele falsche Keys; der Lockout hat ausgelöst. |
| `0x37` | requiredTimeDelayNotExpired | Du musst warten, bevor du es erneut versuchst. |
| `0x7E` | subFunctionNotSupportedInActiveSession | Sub-Funktion existiert, nicht in dieser Session. |
| `0x7F` | serviceNotSupportedInActiveSession | Service existiert, nicht in dieser Session. |
| `0x78` | requestCorrectlyReceived-ResponsePending | Kein Fehler: auf die echte Antwort warten. |

## "Nicht hier" von "nicht jetzt" unterscheiden

Die nützlichste Unterscheidung während der Enumeration ist die zwischen einem Service, der nicht existiert, und einem, der existiert, aber hinter einer Session oder SecurityAccess gesperrt ist. Die Codes machen das explizit.

- `0x11` serviceNotSupported: der SID fehlt. Hör auf, ihn zu proben.
- `0x7F` serviceNotSupportedInActiveSession: der SID ist da, du bist in der falschen Session. Sende nach `10 03` (Extended) oder, vorsichtig, `10 02` (Programming) erneut.
- `0x33` securityAccessDenied: der SID ist da und in dieser Session erreichbar, braucht aber zuerst eine entsperrte SecurityAccess-Stufe.

Ein RoutineControl-Probe, der `7F 31 33` zurückgibt, ist also keine Sackgasse. Es ist die Bestätigung, dass `0x31` hier existiert und dass etwas Schützenswertes hinter `0x27` sitzt. Dieses eine Byte lenkt den ganzen Test auf das Seed/Key-Tor.

## Response Pending, und die ECUs, die es missbrauchen

`0x78` ist das ECU, das um mehr Zeit bittet. Das korrekte Tester-Verhalten ist, den P2*-Timer zurückzusetzen und weiter auf eine positive Antwort oder einen anderen NRC zu warten. Byte für Byte:

```
tx 31 01 FF 00    RoutineControl startRoutine 0xFF00
rx 7F 31 78       Response Pending, weiter warten
rx 7F 31 78       arbeitet noch
rx 71 01 FF 00    finale positive Antwort
```

Zwei Muster sind selbst Findings. Ein ECU, das `0x78` sendet und nie nachliefert, hängt jeden Tester, der das Protokoll einhält. Ein ECU, das einen endlosen Strom von `0x78` sendet, lässt sich nutzen, um eine Session, sogar eine Programming-Session, viel länger offen zu halten als vorgesehen.

## NRCs bei SecurityAccess nutzen

Die SecurityAccess-Codes bilden eine kleine Zustandsmaschine, die du beobachten kannst. Ein gesundes Tor läuft durch sie hindurch:

```
tx 27 01          requestSeed Level 1
rx 67 01 A1 B2    Seed zurückgegeben
tx 27 02 00 00    sendKey (falsch)
rx 7F 27 35       invalidKey
...wiederholen...
rx 7F 27 36       exceedNumberOfAttempts (Lockout ausgelöst)
tx 27 02 00 00    sendKey
rx 7F 27 37       requiredTimeDelayNotExpired
```

Ein ECU, das endlos `0x35` antwortet und nie zu `0x36` und `0x37` eskaliert, hat keinen Attempt-Counter und keine Verzögerung. Das ist ein schwaches Tor, und die NRC-Spur ist der Nachweis.

## Wo die Codes in die Irre führen

Nicht jedes ECU nutzt die Tabelle sauber. Manche antworten `0x10` generalReject auf alles Unbekannte und löschen so den Unterschied zwischen "nicht unterstützt" und "nicht in dieser Session". Manche geben `0x22` conditionsNotCorrect zurück, wo `0x31` korrekt wäre. Eine einzelne Antwort ist daher ein schwacher Nachweis. Die verlässliche Methode ist statistisch: jeden SID über alle entdeckten Sessions proben und die Response-Codes vergleichen, sodass auch ein falsch beschriftetes ECU seine echte Karte offenlegt. Genau das macht die Enumeration von AutoST, indem sie jeden Service aus seinem Antwortmuster klassifiziert statt einer einzigen Antwort zu trauen, und unser freier [UDS-NRC-Decoder](/de/tools/uds-nrc-decoder) löst einen einzelnen Code auf, wenn du nur den Namen brauchst.

## FAQ

**Wie ist eine negative UDS-Antwort aufgebaut?**

Aus drei Bytes: 0x7F, dem Service-Identifier des abgelehnten Requests und dem Negative Response Code. Ein Tester, der 22 F1 90 sendet und 7F 22 31 erhält, lernt, dass der Service existiert, der Data Identifier aber out of range ist.

**Ist Response Pending (0x78) ein Fehler?**

Nein. requestCorrectlyReceived-ResponsePending sagt dem Tester, dass das ECU mehr Zeit braucht, also verlängert der Tester seinen P2*-Timeout und wartet. Ein ECU, das 0x78 sendet und dann nie antwortet, ist selbst ein Finding, weil es den Tester hängen lässt.

**Warum antworten ECUs auf einen unbekannten DID mit 0x31 statt 0x7F?**

requestOutOfRange (0x31) ist die korrekte Antwort auf einen Data Identifier, den das ECU nicht unterstützt. serviceNotSupportedInActiveSession (0x7F) heißt, der ganze Service ist in der aktuellen Session nicht verfügbar. Beides zu verwechseln ist häufig und erschwert die Enumeration.

## Sources

- [ISO 14229-1:2020 Straßenfahrzeuge, Unified diagnostic services (UDS), Teil 1: Anwendungsschicht, Anhang A](https://www.iso.org/standard/72439.html)
- [ISO 15765-2:2016 Straßenfahrzeuge, Diagnosekommunikation über CAN (DoCAN), Teil 2: Transportprotokoll und Netzwerkschicht](https://www.iso.org/standard/84211.html)

## Related

- [NRC (Negative Response Code)](https://auto-st.com/de/glossar/nrc)
- [UDS (Unified Diagnostic Services)](https://auto-st.com/de/glossar/uds)
- [UDS-Negative-Response-Code-Decoder](https://auto-st.com/de/tools/uds-nrc-decoder)
- [Kenne jede Tür ins ECU.](https://auto-st.com/de/uds-enumeration)
- [Hält dein Seed/Key wirklich?](https://auto-st.com/de/security-access-test)
- [UDS Enumeration erklärt: wie man ein ECU sicher abbildet](https://auto-st.com/de/insights/uds-enumeration-explained)

---
AutoST by Zyberum. Canonical page: https://auto-st.com/de/insights/uds-negative-response-codes-erklaert
