Zwei Kopfzeilen, zwei verschiedene Aussagen
Der Sunset-Header ist in RFC 8594 beschrieben und beantwortet eine einzige Frage: Bis wann ist mit dieser Adresse zu rechnen? Sein Wert ist ein Zeitstempel im HTTP-Datumsformat und soll in der Zukunft liegen (RFC 8594). Die Spezifikation ist dabei bewusst vorsichtig formuliert. Ein Client soll den Zeitstempel als Hinweis behandeln, denn es ist nicht zugesichert, dass die Ressource bis zu diesem Zeitpunkt verfügbar bleibt und danach verschwindet (RFC 8594). Für den Betrieb heißt das: Der Termin taugt als frühester Handlungsanlass, nicht als verlässlicher Endpunkt der Planung. Ein Liegenlassen bis zu dem genannten Tag ist die schlechtere Lesart.
Der Deprecation-Header stammt aus RFC 9745, seit März 2025 auf dem Standards Track, und beantwortet eine andere Frage: Ab wann gilt diese Adresse als abgekündigt? Entscheidend ist der Zusatz aus derselben Spezifikation — die Abkündigung ändert das Verhalten der Ressource nicht (RFC 9745). Ein abgekündigter Endpunkt antwortet weiter, liefert dieselben Daten und denselben Statuscode. Genau deshalb bleibt er in einer Überwachung, die auf Erreichbarkeit prüft, monatelang unauffällig: Die Ankündigung steht im Kopf, das Ergebnis bleibt grün.
- Deprecation nennt den Zeitpunkt, ab dem eine Ressource als abgekündigt gilt; das Verhalten der Ressource ändert sich dadurch nicht (RFC 9745).
- Sunset nennt den Zeitpunkt, an dem die Ressource voraussichtlich nicht mehr antwortet (RFC 8594).
- Link mit der Beziehung deprecation verweist auf eine für Menschen gedachte Beschreibung der Abkündigung (IANA).
- Link mit der Beziehung sunset verweist auf eine Beschreibung der Stilllegungsregeln des Kontexts (IANA).
- Beide Felder zusammen ergeben ein Fenster: Anfang der Abkündigung und voraussichtliches Ende der Erreichbarkeit.
RFC 8594 unterscheidet die beiden Phasen ausdrücklich. In der ersten Phase ist die Schnittstelle weiter in Betrieb und kann benutzt werden; für diese Phase ist der Sunset-Header nach dieser Lesart nicht angebracht. Angebracht ist er für die zweite Phase, in der die Schnittstelle oder eine bestimmte Version tatsächlich nicht mehr antwortet (RFC 8594). Wer beide Stufen getrennt überwacht, bekommt zwei Signale statt einem: die Ankündigung als Vorwarnung und das Abschaltdatum als Frist.
Zwei Kopfzeilen, zwei Datumsformate
Die häufigste Ursache dafür, dass eine Prüfregel nichts findet, ist nicht der fehlende Kopf, sondern das falsch gelesene Datum. Die beiden Felder benutzen unterschiedliche Formate, und das ist kein Versehen: Der Sunset-Wert ist ein HTTP-Zeitstempel, der Deprecation-Wert dagegen ein strukturiertes Feld vom Typ Date (RFC 9745). RFC 9745 weist an derselben Stelle selbst darauf hin, dass der Sunset-Header aus historischen Gründen ein anderes Datenformat verwendet, und legt zugleich fest, dass der Sunset-Zeitpunkt nicht früher liegen darf als der Deprecation-Zeitpunkt (RFC 9745).
HTTP/2 200
deprecation: @1688169599
sunset: Sun, 30 Jun 2024 23:59:59 GMT
link: <https://api.example.invalid/deprecation-info>; rel="deprecation"; type="text/html"
link: <https://api.example.invalid/sunset-policy>; rel="sunset"
content-type: application/json
cache-control: no-store
Beim Sunset-Wert gilt die Grammatik aus RFC 9110: Ein Empfänger, der einen Zeitstempel in einem HTTP-Feld auswertet, muss alle drei HTTP-Datumsformate annehmen, während ein Sender nur das IMF-fixdate-Format erzeugen darf (RFC 9110). Die Zeitangabe ist koordinierte Weltzeit, in den ersten beiden Formaten mit dem Kürzel GMT gekennzeichnet (RFC 9110). Der Deprecation-Wert dagegen ist ein Delta in Sekunden seit dem 1. Januar 1970, in der Übertragung durch ein vorangestelltes @ von einer gewöhnlichen Ganzzahl unterschieden; ein Parser muss dabei alle Tage der Jahre 1 bis 9999 tragen (RFC 9651). Wer beide Werte mit derselben Funktion einliest, bekommt bei einem der beiden Felder verlässlich eine ungültige Zeitangabe.
Ein Abschalttermin in koordinierter Weltzeit trifft je nach Jahreszeit auf eine andere lokale Uhrzeit. Wer die Restfrist im Dashboard in Ortszeit anzeigt, rechnet zweimal um: einmal beim Auslesen, einmal beim Anzeigen. Welche Fehler dabei entstehen und warum ein Wechsel der Sommerzeit ganze Auswertungen verschiebt, steht im Beitrag Zeitumstellung im Monitoring. Für die Alarmregel selbst ist es erfahrungsgemäß ruhiger, die Restfrist in ganzen Tagen zu führen und die Uhrzeit nur im Alarmtext mitzugeben.
Warum ein grünes Monitoring die Ankündigung übersieht
Eine übliche Schnittstellenprüfung stellt drei Fragen: Antwortet die Adresse, antwortet sie schnell genug, kommt der erwartete Statuscode zurück? Ein abgekündigter Endpunkt beantwortet alle drei Fragen sauber. Er antwortet mit 200, er antwortet in derselben Zeit wie in der Woche davor, und sein Rumpf enthält dieselben Felder. Die einzige Änderung steht in einer Zeile, die eine reine Erreichbarkeitsprüfung gar nicht ansieht. Wie eine Prüfung aussieht, die über den Statuscode hinausgeht, beschreibt der Beitrag API-Monitoring: Endpunkte überwachen.
Dazu kommt eine zweite Blindstelle: Antwortköpfe werden selten aufbewahrt. Wer nach einem Ausfall im Protokoll nachsieht, findet Statuscodes und Zeiten, aber keinen Kopf — die Ankündigung war da und ist nirgends festgehalten. Dieselbe Lücke betrifft die umgekehrte Richtung, wenn ein Kopf zu viel verrät statt zu wenig; diesen Fall beschreibt der Beitrag Versionsbanner und Server-Header. Der praktische Schluss ist in beiden Richtungen derselbe: Der Antwortkopf gehört in die Prüfung und in die Aufbewahrung, nicht erst in die Fehlersuche.
Ein Endpunkt, der sein eigenes Abschaltdatum mitsendet, ist kein Risiko. Er wird erst dann zu einem, wenn die Prüfung nur bis zum Statuscode liest.
— XICTRAQ
Die Prüfregel: eine Zeile im Prüfauftrag
Technisch ist der Aufwand klein. Eine Schnittstellenprüfung, die Bedingungen auf Antwortköpfe kennt, braucht dafür keine zusätzliche Prüfung, sondern eine zusätzliche Bedingung im bestehenden Auftrag. Wie solche Bedingungen und Schwellenwerte aufgebaut sind, zeigt der Beitrag Assertions und Schwellenwerte im API-Monitoring. Der erste Schritt ist ohnehin von Hand erledigt und dauert eine Minute.
Der dritte Befehl ist der eigentliche Punkt. Der Deprecation-Wert ist ohne Umrechnung nicht lesbar, und eine Regel, die den Rohwert nur auf Vorhandensein prüft, meldet auch dann noch, wenn der Termin längst verstrichen ist. Sinnvoll ist deshalb, den Wert in ein Datum zu überführen und daraus die Restfrist zu rechnen. Die Zahl, die am Ende im Alarmtext steht, ist die verbleibende Zeit — nicht der Zeitstempel.
| Signal im Antwortkopf | Was es aussagt | Was daraus folgt |
|---|---|---|
| Deprecation gesetzt, Sunset fehlt | Abkündigung ohne Abschalttermin | Ablösung planen, beim Anbieter nach dem Termin fragen |
| Deprecation und Sunset gesetzt | Ankündigung mit Frist | Restfrist rechnen, Umstellung terminieren |
| Sunset gesetzt, Deprecation fehlt | Abschalttermin ohne formale Abkündigung | wie eine Abkündigung behandeln |
| Sunset-Datum verschiebt sich nach vorn | Die Frist verkürzt sich | Eskalation, Planung neu bewerten |
| Sunset-Datum liegt in der Vergangenheit | Abschaltung kann jederzeit erfolgen | als Vorfall behandeln, nicht als Warnung |
| Kopf war gesetzt und ist verschwunden | Zurückgezogene Ankündigung oder Konfigurationsfehler | beim Anbieter nachfragen, Stand festhalten |
| Link mit der Beziehung deprecation | Beschreibung für Menschen verlinkt | Adresse in die Ablösungsakte übernehmen |
Vier Signale, die eine Regel auslösen sollten
Eine Bedingung im API-Monitoring prüft, ob der Antwortkopf Deprecation oder Sunset trägt. Solange keiner der beiden Namen auftaucht, bleibt die Prüfung still; taucht einer auf, entsteht ein Ereignis mit dem vollständigen Kopf im Protokoll.
Aus dem Sunset-Datum wird die verbleibende Zeit gerechnet und gegen gestufte Schwellen geprüft. Erfahrungsgemäß reichen vier Stufen, damit die erste Meldung nicht in derselben Woche liegt wie die Abschaltung selbst.
Ein Termin, der sich nach vorn bewegt, ist das wichtigste Signal von allen, weil er die bereits gemachte Planung entwertet. Die Regel vergleicht den gelesenen Wert mit dem zuletzt gespeicherten und meldet jede Abweichung über die Alarmierung.
Auch der umgekehrte Fall gehört gemeldet: Ein Kopf, der gesetzt war und nicht mehr kommt, ist entweder eine zurückgezogene Abkündigung oder ein Konfigurationsfehler beim Anbieter. Beides will man wissen, bevor man sich auf den alten Stand verlässt.
Diese vier Regeln lassen sich auf denselben Prüfauftrag legen, der ohnehin läuft. Wichtig ist die Trennung der Alarmwege: Die Ankündigung ist eine Planungsmeldung an die Entwicklung, die verkürzte Frist eine Betriebsmeldung an die Bereitschaft. Werden beide über denselben Kanal in derselben Dringlichkeit zugestellt, gewöhnt sich das Team an die Meldung — der Beitrag Monitoring-Alerts richtig konfigurieren beschreibt, wie sich das vermeiden lässt. Dieselbe Trennung gilt für verwandte Kopfzeilen wie die Angaben zu Kontingenten, die im Beitrag Rate Limits und der Statuscode 429 beschrieben sind.
Aus einem Datum wird eine Vorwarnzeit
Ein Termin allein steuert nichts. Steuerbar wird er erst, wenn daraus eine Zahl in Tagen wird, die sich gegen Schwellen prüfen lässt. Die Rechnung ist unspektakulär, hat aber zwei Fallen. Der Deprecation-Wert ist ein Sekundenwert und muss mit tausend multipliziert werden, bevor ein Zeitobjekt daraus entsteht. Und ein Sunset-Datum in der Vergangenheit ist keine negative Frist, sondern ein Zustand: RFC 8594 empfiehlt für diesen Fall die vorsichtige Lesart, einen Zeitstempel in der Vergangenheit als Gegenwart zu behandeln, weil die Ressource dann jederzeit verschwinden kann (RFC 8594).
// Antwortkopf auswerten: zwei Felder, zwei Formate, eine Restfrist
function fristAuslesen(headers) {
const dep = headers.get('deprecation'); // strukturiertes Feld: @<sekunden>
const sun = headers.get('sunset'); // HTTP-Datum: IMF-fixdate
const depDatum = dep && /^@-?\d+$/.test(dep.trim())
? new Date(Number(dep.trim().slice(1)) * 1000)
: null;
const sunDatum = sun ? new Date(Date.parse(sun)) : null;
if (sunDatum && Number.isNaN(sunDatum.getTime())) {
return { gemessen: false, grund: 'Sunset-Datum nicht lesbar' };
}
if (!depDatum && !sunDatum) {
return { gemessen: false, grund: 'kein Abschaltsignal im Kopf' };
}
const restTage = sunDatum
? Math.floor((sunDatum.getTime() - Date.now()) / 86400000)
: null;
return {
gemessen: true,
deprecationAb: depDatum,
abschaltung: sunDatum,
restTage, // negativ: Termin verstrichen
sofortBehandeln: restTage !== null && restTage <= 0
};
}
Der Rückgabewert trennt bewusst zwischen gemessen und nicht gemessen. Ein fehlender Kopf ist kein Wert null und keine Frist von tausend Tagen, sondern eine Messung, die nicht stattgefunden hat. Wer an dieser Stelle einen Ersatzwert einsetzt, baut sich eine Kennzahl, die dauerhaft grün aussieht, weil sie an dieser Stelle gar keine Messung kennt.
- 180 Tage vor dem Termin: Meldung an die Entwicklung, Aufnahme in die Ablösungsplanung, Prüfung, ob eine Nachfolgeversion benannt ist.
- 90 Tage vor dem Termin: Umstellung terminiert, Testumgebung gegen die Nachfolgeversion geprüft, Rückweg beschrieben.
- 30 Tage vor dem Termin: Umstellung abgeschlossen oder ein benannter Grund im Vorgang, warum sie es nicht ist.
- 7 Tage vor dem Termin: Eskalation an die Bereitschaft und ein beschriebener Notbetrieb für den Fall, dass der Termin gehalten wird.
- Termin verstrichen: Behandlung als Vorfall, unabhängig davon, ob die Adresse noch antwortet.
Die unangenehmste Änderung ist nicht das Auftauchen eines Sunset-Kopfes, sondern seine Verschiebung. Ein Datum, das von Dezember auf September springt, entwertet jede Planung, die auf dem alten Wert beruhte — und es fällt ohne gespeicherten Vorwert gar nicht auf. Deshalb gehört der zuletzt gelesene Wert in die Prüfung selbst, nicht nur in den Alarmtext. Wie eine solche Meldung von der Erkennung bis zur Übergabe läuft, beschreibt der Beitrag Incident-Management und Eskalation.
Wenn der Anbieter gar nichts setzt
Die beiden Kopfzeilen sind Empfehlungen, keine Pflicht. RFC 8594 trägt den Status Informational, RFC 9745 den Status Standards Track; beide beschreiben, wie eine Ankündigung aussieht, nicht dass sie erfolgen muss. Belastbare Zahlen dazu, wie verbreitet die beiden Felder in freier Wildbahn sind, liegen hier nicht in einer zitierbaren Primärquelle vor — entsprechend steht in diesem Beitrag bewusst keine Verbreitungsquote. Praktisch heißt das: Die Prüfregel auf den Kopf ist ein Gewinn, wo sie greift, und ersetzt die Beobachtung der übrigen Signale nicht.
- Änderungshinweise und Versionsverzeichnis des Anbieters als eigene Prüfung, nicht als Lesezeichen im Browser.
- Ein Statuscode, der sich ändert: 301 auf eine neue Version, 410 auf eine entfernte Ressource.
- Ein Antwortrumpf, der neben den Daten plötzlich ein Hinweisfeld trägt, ohne dass sich der Statuscode ändert.
- Zertifikats- und Domainfristen der Schnittstelle, weil ein auslaufender Vertrag sich dort oft zuerst zeigt.
- Der eigene Vertrag mit dem Anbieter, in dem die Ankündigungsfrist steht, sofern eine vereinbart wurde.
Der letzte Punkt ist der wirksamste und zugleich der am seltensten geprüfte. Wo die Ankündigungsfrist vertraglich festgehalten ist, lässt sie sich mit dem Datum aus dem Kopf abgleichen: Eine Abschaltung zwei Wochen nach der Ankündigung, obwohl drei Monate vereinbart sind, ist ein Vertragsthema und kein Technikthema. Welche Pflichten eine solche Vereinbarung sonst noch trägt, beschreibt der Beitrag Auftragsverarbeitung nach Artikel 28. Auch Fristen, die mit Schnittstellen gar nichts zu tun haben, laufen nach demselben Muster ab — der Beitrag Domainablauf verhindern zeigt den Fall an einer Domain.
Der Tag danach: was ein Client dann sieht
RFC 8594 beschreibt, was nach dem Termin zu erwarten ist: Zugriffe auf die Ressource führen dann voraussichtlich zu clientseitigen Fehlern im 4xx-Bereich, zu Weiterleitungen im 3xx-Bereich, oder der Client kann mit der Ressource überhaupt nicht mehr sprechen (RFC 8594). Für die Überwachung ist das eine brauchbare Erwartungsliste, weil jeder dieser drei Fälle anders aussieht. Ein 404 fällt einer Statuscode-Prüfung sofort auf. Eine 301 auf eine neue Version fällt ihr nicht auf, wenn die Prüfung Weiterleitungen folgt und nur den Endcode bewertet.
Der unangenehmste Ausgang steht in dieser Liste nicht: Die abgeschaltete Adresse antwortet weiter mit 200 und liefert eine leere Liste, einen Hinweistext oder ein Fehlerobjekt im Rumpf. Statuscode und Antwortzeit bleiben unauffällig, der Datenfluss ist trotzdem abgerissen. Deshalb gehört zu jeder Schnittstellenprüfung eine Bedingung auf den Inhalt: ein erwartetes Feld, ein Mindestumfang, ein Schema. Wie ein stiller Inhaltsfehler aussieht, wenn nicht die Schnittstelle, sondern die Zeichenkodierung kippt, zeigt der Beitrag Kaputte Umlaute nach einer Migration.
Die Sunset-Angabe bezieht sich dabei auf genau die Ressource, die sie zurückgibt, und kündigt das bevorstehende Ende dieser einen Ressource an (RFC 8594). Eine Ankündigung auf einem Endpunkt sagt also nichts über die Nachbarendpunkte derselben Schnittstelle aus. Wer eine Schnittstelle mit dreißig Adressen betreibt und nur die Startadresse prüft, bekommt die Ankündigung für die übrigen neunundzwanzig nicht zu sehen. Praktisch bedeutet das: Die Prüfregel gehört auf jede Adresse, die im eigenen Code aufgerufen wird — und diese Liste zu erstellen ist der eigentliche Aufwand, nicht die Regel.
Die eigene Schnittstelle: den Kopf selbst setzen
Die Perspektive dreht sich, sobald man selbst eine Schnittstelle anbietet. Dann ist der Kopf kein Signal, das man liest, sondern eines, das man sendet — und zwar auf jeder Antwort der betroffenen Ressource, nicht nur auf einer Ankündigungsseite. Beide Felder stehen im Feldnamenregister der IANA mit dem Status permanent: Deprecation mit dem strukturierten Typ Item, Sunset ohne Typangabe (IANA). Ein eigener Kopfname mit vorangestelltem X ist damit weder nötig noch hilfreich.
location /v1/ {
# Abkündigung einer Endpunktversion: beide Kopfzeilen auf jede Antwort
add_header Deprecation "@1688169599" always;
add_header Sunset "Sun, 30 Jun 2024 23:59:59 GMT" always;
add_header Link "<https://api.example.invalid/deprecation-info>; rel=\"deprecation\"; type=\"text/html\"" always;
proxy_pass http://127.0.0.1:8080;
}
Zwei Regeln gehören dazu. Erstens die Reihenfolge: Der Zeitstempel im Sunset-Header darf nicht früher liegen als der im Deprecation-Header, und wo das doch passiert, sollte der Anwendungsentwickler beim Anbieter nachfragen (RFC 9745). Zweitens der Verweis: Ein Link mit der Beziehung deprecation zeigt auf eine für Menschen gedachte Beschreibung der Abkündigung, ein Link mit der Beziehung sunset auf eine Beschreibung der Stilllegungsregeln des Kontexts (IANA). Der Link-Header selbst ist in RFC 8288 beschrieben und dient dazu, eine oder mehrere Verknüpfungen in HTTP-Kopfzeilen zu serialisieren (RFC 8288). Wer beides setzt, gibt einem fremden Monitoring genau das, was man selbst gern vorfinden würde.
Ein Eintrag im Änderungsverzeichnis erreicht die Menschen, die ihn lesen. Eine Kopfzeile erreicht jedes System, das die Schnittstelle aufruft — auch das, dessen Betreiber das Verzeichnis noch nicht geöffnet hat. Beides zusammen kostet eine Konfigurationszeile mehr und erspart erfahrungsgemäß den Anruf am Abschalttag. Prüfen lässt sich das eigene Ergebnis in derselben Minute mit einem Kopfabruf gegen die eigene Adresse.
Was davon in den Betriebskalender gehört
Eine Prüfregel ohne Zuständigkeit erzeugt Meldungen, die im Posteingang altern. Damit aus dem Signal eine Handlung wird, braucht es drei Festlegungen: wer die Meldung annimmt, wo der Vorgang geführt wird und wann er ohne Fortschritt eskaliert. Der technische Teil ist an dieser Stelle bereits erledigt — was fehlt, ist die Zuordnung.
- Bestand aufnehmen: alle fremden Adressen auflisten, die der eigene Code aufruft, mit Version und aufrufendem Dienst.
- Prüfung einrichten: je Adresse eine Bedingung auf Deprecation und Sunset, dazu die bestehende Bedingung auf Inhalt und Antwortzeit.
- Schwellen setzen: gestufte Restfristen mit unterschiedlichen Empfängern statt einer einzigen Schwelle für jede Meldung.
- Vorwert speichern: den zuletzt gelesenen Termin je Adresse aufbewahren, damit eine Verschiebung überhaupt auffallen kann.
- Zuständigkeit hinterlegen: je Adresse eine benannte Rolle, die eine Ankündigung annimmt und den Vorgang führt.
- Quartalsweise nachziehen: neue Adressen aus dem Code in die Liste übernehmen, entfallene entfernen.
Bevor eine Regel eingerichtet wird, ist ein einmaliger Kopfabruf über die gesamte Adressliste die schnellere Auskunft. Er zeigt in wenigen Minuten, ob im Bestand überhaupt eine Ankündigung liegt und wie viele Adressen betroffen sind. Erst danach lässt sich entscheiden, ob eine tägliche oder eine stündliche Prüfung angemessen ist. Für Adressen, die nur zeitgesteuert aufgerufen werden, ist zusätzlich ein Heartbeat sinnvoll, weil dort ein ausbleibender Lauf das erste Symptom ist.
Abkündigungen als dauerhafte Prüfregel führen
Der Sunset-Header und der Deprecation-Header lösen kein Problem, das ohne sie unlösbar wäre. Sie verschieben den Zeitpunkt, zu dem man von einer Abschaltung erfährt: von der Störungsmeldung eines Anwenders auf einen Termin, der Monate vorher in jeder Antwort steht. Der Aufwand dafür ist eine Bedingung im bestehenden Prüfauftrag und eine gepflegte Liste der eigenen Abhängigkeiten. Wer das einmal einrichtet, tauscht eine Überraschung gegen eine Frist — und Fristen lassen sich planen. Wie beides in einem laufenden Betrieb zusammenspielt, lässt sich in der Demo ansehen; die Zustellung der Meldungen liegt in der Alarmierung.
Die technischen Angaben in diesem Beitrag stammen aus den Spezifikationen selbst: RFC 8594 zum Sunset-Header, RFC 9745 zum Deprecation-Header, RFC 9110 zum HTTP-Datumsformat, RFC 9651 zu strukturierten Feldern und RFC 8288 zum Link-Header. Die Registerangaben stammen aus dem Feldnamenregister und dem Register der Verknüpfungsbeziehungen der IANA. Verbreitungszahlen zur tatsächlichen Nutzung der beiden Kopfzeilen werden bewusst nicht genannt, weil dafür hier keine zitierbare Primärquelle vorliegt.