
X-Robots-Tag: noindex für PDFs, Bilder und alles ohne HTML
X-Robots-Tag ist das Robots-Meta-Tag als HTTP-Kopfzeile. Es trägt dieselben Anweisungen — noindex, nofollow, nosnippet und die übrigen —, steht aber nicht im HTML, sondern in der Antwort des Servers. Deshalb funktioniert es auch bei Dateien, die gar kein HTML haben.
HTTP/1.1 200 OK
Content-Type: application/pdf
X-Robots-Tag: noindex
Google formuliert den Einsatzzweck in einem Satz: Wer die Indexierung von Nicht-HTML-Ressourcen wie PDFs, Video- oder Bilddateien blockieren will, soll statt des Meta-Tags den X-Robots-Tag-Antwortheader verwenden. Was noindex selbst tut und wann es das falsche Werkzeug ist, steht in noindex: was es tut und wann es das Falsche ist — hier geht es um die Kopfzeile, ihre Konfiguration und die Fehler, die man mit ihr machen kann.
Wann der Header, wann das Meta-Tag#
Ein Meta-Tag braucht einen <head>. Ein PDF hat keinen, ein Bild auch nicht, eine CSV-Datei erst recht nicht. Für alles, was der Server nicht als HTML ausliefert, ist die Kopfzeile der einzige Weg, eine Robots-Anweisung mitzugeben.
Bei HTML-Seiten sind beide Wege gleichwertig. Der Header steht nicht über dem Meta-Tag, und das Meta-Tag nicht über dem Header. Google kennt keine Rangfolge nach dem Ort, sondern nur eine Regel für Widersprüche: Bei Konflikten zwischen Robots-Regeln wird die restriktivere angewendet. Das Beispiel in der Dokumentation ist max-snippet:50 neben nosnippet — es gilt nosnippet. Für die Praxis heißt das: Ein noindex in der Kopfzeile lässt sich nicht durch ein index im HTML aufheben, und umgekehrt auch nicht.
Der Header hat trotzdem einen Vorzug: Er wird zentral gesetzt. Eine Zeile in der Serverkonfiguration deckt alle PDFs eines Verzeichnisses ab, ohne dass jemand die Dateien anfasst. Dieselbe Reichweite ist später die Gefahr.

Was in der Kopfzeile stehen darf#
Google unterstützt im X-Robots-Tag dieselben Regeln wie im Meta-Tag:
noindex— nicht in den Suchergebnissen zeigennofollow— den Verweisen nicht folgennone— beides zusammennosnippet— keinen Textausschnitt und keine Videovorschaumax-snippet:[Zahl],max-image-preview:[Größe],max-video-preview:[Sekunden]— Begrenzungen für Vorschauennoimageindex— Bilder dieser Seite nicht indexierennotranslate— keine Übersetzung anbietenunavailable_after:[Datum]— nach dem Zeitpunkt nicht mehr zeigenindexifembedded— wirkt nur zusammen mitnoindexall— keine Einschränkung, der Standard
Mehrere Regeln trennt ein Komma. Es dürfen auch mehrere X-Robots-Tag-Zeilen in derselben Antwort stehen; Google fasst sie zusammen. Groß- und Kleinschreibung spielt weder beim Header-Namen noch bei den Werten eine Rolle.
Vor die Regeln lässt sich ein Crawler-Name setzen. Das Beispiel aus der Google-Dokumentation:
X-Robots-Tag: googlebot: nofollow
X-Robots-Tag: otherbot: noindex, nofollow
Regeln ohne Crawler-Namen gelten für alle. Google selbst wertet als Namen googlebot für die Textsuche und googlebot-news für Nachrichten; andere Namen ignoriert Google.
Apache: .htaccess oder Hauptkonfiguration#
Für alle PDFs unterhalb eines Verzeichnisses:
<FilesMatch "\.pdf$">
Header set X-Robots-Tag "noindex, nofollow"
</FilesMatch>
<FilesMatch> begrenzt die eingeschlossenen Anweisungen auf Dateinamen, die dem regulären Ausdruck entsprechen, und ist in Serverkonfiguration, virtuellem Host, Verzeichnisblock und .htaccess erlaubt. Für mehrere Endungen: "\.(pdf|docx?|xlsx?)$". Google zeigt in der eigenen Dokumentation dieselbe Konstruktion als <Files ~ "\.pdf$">; Apache selbst nennt <FilesMatch> die bevorzugte Form.
Header set setzt die Kopfzeile und ersetzt eine vorhandene gleichen Namens. Das ist gewollt: Steht schon ein X-Robots-Tag in der Antwort, wird er ersetzt, statt dass zwei Zeilen nebeneinander ausgeliefert werden.
Zwei Bedingungen, an denen der Block scheitert:
mod_headersmuss geladen sein. Das Modul hat bei Apache den Status „Extension" und ist nicht in jeder Installation aktiv. Fehlt es, kennt der Server die AnweisungHeadernicht — in der.htaccessergibt eine unbekannte Anweisung einen500.- In der
.htaccessbraucht esAllowOverride FileInfo(oderAll). Die Apache-Dokumentation ordnet diemod_headers-Anweisungen dieser Gruppe zu. StehtAllowOverride None, wird die Datei gar nicht erst gelesen; ist eine andere Gruppe freigegeben, aber nichtFileInfo, antwortet der Server mit einem internen Fehler.
Wer eine ganze Staging-Umgebung sperren will, setzt die Zeile ohne <FilesMatch> in den virtuellen Host:
Header set X-Robots-Tag "noindex, nofollow"
Das gilt dann für jede Antwort mit Status 2xx. Soll die Zeile auch bei Fehlerseiten und Weiterleitungen mitgehen, heißt es Header always set — laut Dokumentation landen nur die always-Kopfzeilen auch in Antworten, die kein Erfolg sind.
nginx: add_header und seine Vererbungsfalle#
Dasselbe für PDFs:
location ~* \.pdf$ {
add_header X-Robots-Tag "noindex, nofollow";
}
~* steht für einen regulären Ausdruck ohne Beachtung der Groß- und Kleinschreibung, report.PDF ist also mit erfasst. nginx prüft reguläre location-Blöcke in der Reihenfolge der Konfigurationsdatei und nimmt den ersten Treffer — steht weiter oben schon ein location ~* \.(pdf|zip)$ für einen Cache-Header, kommt dieser Block nie an die Reihe.
add_header ist in http, server und location erlaubt. Für eine ganze Umgebung gehört die Zeile in den server-Block:
server {
server_name staging.beispiel.de;
add_header X-Robots-Tag "noindex, nofollow";
# ...
}
Und hier sitzt die Falle, die in keiner Kurzanleitung steht. Die nginx-Dokumentation hält fest: add_header-Anweisungen werden von der übergeordneten Ebene nur dann geerbt, wenn auf der aktuellen Ebene keine eigene add_header-Anweisung steht. Es ist keine Ergänzung, sondern ein Austausch.
server {
add_header X-Robots-Tag "noindex, nofollow";
location /downloads/ {
add_header Cache-Control "public, max-age=86400";
# X-Robots-Tag fehlt hier — der Block hat sein eigenes add_header
}
}
Alles unter /downloads/ ist damit indexierbar, obwohl der server-Block das Gegenteil sagt. Wer die Umgebung mit curl nur an der Startseite prüft, sieht den Header und ist beruhigt. Abhilfe: die Zeile in jedem location-Block wiederholen, der ein eigenes add_header hat. Seit nginx 1.29.3 gibt es außerdem add_header_inherit, mit dem sich die Vererbungsregel umstellen lässt.
Ein zweiter Punkt aus derselben Dokumentation: add_header wirkt nur bei den Statuscodes 200, 201, 204, 206, 301, 302, 303, 304, 307 und 308. Für alles andere braucht es den Parameter always.
Prüfen mit curl -I#
Der Test dauert eine Sekunde:
curl -I -L https://www.beispiel.de/dateien/preisliste.pdf
-I holt nur die Kopfzeilen, per HEAD-Anfrage. -L folgt Weiterleitungen, damit man die Antwort der Zieladresse sieht und nicht die einer 301. In der Ausgabe muss eine Zeile X-Robots-Tag: noindex, nofollow stehen — oder eben nicht, je nachdem, was man erwartet.
Mindestens drei Adressen prüfen: eine HTML-Seite, ein PDF, eine Datei aus jedem Block mit eigener Header-Zeile. Der Grund steht einen Abschnitt weiter oben.
Was Google tatsächlich gesehen hat, zeigt die URL-Prüfung der Search Console: Unter „Gecrawlte Seite anzeigen" stehen HTTP-Anfrage und -Antwort, und die Zeile „Indexierung zulässig?" nennt den Grund, wenn die Seite ausgeschlossen ist. Der Live-Test macht dasselbe mit der aktuellen Fassung. Im Bericht zur Seitenindexierung landet eine Seite mit Header-noindex unter „URL als „noindex" markiert" — der Eintrag nennt die Anweisung, nicht den Ort.

Die drei Fallen im Betrieb#
1. Die robots.txt-Sperre. Robots-Meta-Tags und X-Robots-Tag-Header werden beim Crawlen entdeckt. Darf Google die Adresse laut robots.txt nicht abrufen, werden die Regeln nicht gefunden und ignoriert — Google schreibt ausdrücklich, dass Adressen mit solchen Regeln nicht vom Crawling ausgeschlossen sein dürfen. Wer /dateien/ in der robots.txt sperrt und den PDFs dort ein noindex mitgibt, hat das noindex weggeworfen. Ein PDF, auf das von außen verlinkt wird, kann dann trotzdem im Index landen. Die Reihenfolge, die funktioniert, steht in Durch robots.txt-Datei blockiert: erst Header, robots.txt offen lassen, warten, dann sperren — wenn überhaupt.
2. Das Staging-noindex, das mit umzieht. Ein noindex im Header ist unsichtbar. Es steht nicht im Quelltext, Strg+U findet nichts. Wird die Serverkonfiguration der Staging-Umgebung beim Livegang kopiert — der virtuelle Host, die .htaccess, der server-Block —, zieht die Zeile mit. Die Seite ist dann live, sieht im Browser richtig aus und fällt nach und nach aus der Suche. Google hält fest, dass es je nach Bedeutung der Seite Monate dauern kann, bis der Googlebot sie wieder besucht — das gilt auch für das Entfernen der Zeile. Deshalb gehört curl -I gegen die Live-Adresse in jede Relaunch-Checkliste, direkt neben die Prüfung der robots.txt.
3. Header und Meta-Tag sagen Verschiedenes. Das passiert, wenn ein Plugin im HTML index, follow schreibt und der Server aus alter Gewohnheit noindex mitschickt — oder umgekehrt. Es gibt keinen Gewinner nach Ort. Die restriktivere Regel gilt, also bleibt die Seite draußen. Wer im HTML ein sauberes Robots-Tag sieht und trotzdem den Eintrag „URL als „noindex" markiert" im Bericht hat, sieht als Nächstes die Kopfzeilen an.
Was nicht hilft#
Beides setzen, um sicherzugehen. Ein noindex als Meta-Tag und dasselbe noch einmal als Header ändern nichts an der Wirkung, verdoppeln aber die Stellen, an denen man es später wieder entfernen muss.
Ein Präfix für jeden Crawler. googlebot: noindex, bingbot: noindex, … ist länger als noindex und deckt weniger ab. Das Präfix ist für Regeln gedacht, die gezielt nur für einen Crawler gelten sollen.
Die robots.txt als Ersatz. Sie verhindert das Abrufen, nicht die Aufnahme in den Index. Für „soll nicht in der Suche auftauchen" ist sie das falsche Werkzeug, und in Kombination mit dem Header macht sie ihn unwirksam.
Den Header setzen und nicht prüfen. Ein Header-Block ohne mod_headers, ein add_header, das von einem anderen add_header verdrängt wird, ein Cache davor, der noch die alte Antwort ausliefert — jede dieser Konfigurationen sieht in der Datei richtig aus. Ob sie ankommt, sagt nur die Antwort des Servers.
Der ehrliche Schluss#
Der X-Robots-Tag ist eine Zeile mit großer Reichweite. Für PDFs, Bilder und Downloads ist er der einzige Weg zu einem noindex, für Staging-Umgebungen der bequemste — und genau deshalb nach jedem Livegang und jeder Serverumstellung zu prüfen. Ob eine Seite daran oder an etwas anderem scheitert, klärt Warum Google Seiten nicht indexiert. Und wenn Dubletten gebündelt statt ausgeschlossen werden sollen, ist die Antwort nicht dieser Header, sondern der Canonical-Tag — den es für Dateien ohne HTML ebenfalls als Kopfzeile gibt.
Quellen#
- Robots-Meta-Tag, data-nosnippet und X-Robots-Tag — unterstützte Regeln, Crawler-Präfix, die Regel für Konflikte, der Absatz zur robots.txt und die Beispiele für Apache und nginx
- Aufnahme in den Google-Suchindex mit noindex blockieren — Header für Nicht-HTML-Ressourcen, Prüfung per URL-Prüfung und der Hinweis, dass ein erneuter Besuch Monate dauern kann
- Apache mod_headers —
Header set, Kontext, OverrideFileInfo, Status „Extension",always - Apache Core: FilesMatch und AllowOverride —
<FilesMatch>mit regulärem Ausdruck;FileInfoumfasst diemod_headers-Anweisungen - nginx ngx_http_headers_module —
add_header, Statuscodes,always, Vererbung nur ohne eigene Anweisung,add_header_inherit - nginx ngx_http_core_module: location —
~und~*, erster Treffer bei regulären Ausdrücken - MDN: X-Robots-Tag — Syntax mit Crawler-Präfix, Antwortheader, Hinweis zur robots.txt
- Search Console: URL-Prüftool — „Gecrawlte Seite anzeigen" mit HTTP-Anfrage und -Antwort, „Indexierung zulässig?", Live-Test
- Search Console: Bericht zur Seitenindexierung — Eintrag „URL als „noindex" markiert"
- curl-Handbuch —
-Iholt nur die Kopfzeilen perHEAD,-Lfolgt Weiterleitungen
Kommentare
Gespeichert werden nur dein Name und dein Text — keine E-Mail-Adresse, keine IP-Adresse, kein Cookie. Jeder Kommentar wird vor der Veröffentlichung gelesen; das dauert meist einen Tag. Näheres in der Datenschutzerklärung.