# Fehlersuche ## Überblick Jede Fehlermeldung, die der Client erzeugen kann, mit Ursache und Behebung. Die Meldungen stammen aus `manage-client/lib/`. Erste Anlaufstelle ist immer: ```bash php manage-client/bin/manage-client.php status ``` und danach das Protokoll in `MANAGE_LOG_FILE` (Standard `data/manage/manage-client.log`, eine JSON-Zeile pro Ereignis): ```bash tail -20 data/manage/manage-client.log | php -r 'while($l=fgets(STDIN)) { $e=json_decode($l,true); echo $e["timestamp"]," ",$e["level"]," ",$e["message"],"\n"; }' ``` ## Konfiguration und Verbindung **`Manage-Client ist nicht konfiguriert. MANAGE_SERVER_URL, MANAGE_INSTANCE und MANAGE_TOKEN müssen in manage-client/config.php gesetzt sein.`** `config.php` fehlt oder einer der drei Werte ist leer. `config.sample.php` kopieren und die Werte aus dem Manage-Server eintragen. Prüfen, ob die Datei wirklich `manage-client/config.php` heißt. **`Manage-Server ist nicht erreichbar: `** Keine Antwort. Mögliche Ursachen: falsche `MANAGE_SERVER_URL`, DNS, Firewall, ausgehende Verbindungen auf dem Hoster gesperrt, TLS-Zertifikat nicht vertrauenswürdig. Prüfen mit `curl -v /api/v1/manifest.php` vom selben Server aus. **`Ungültige Server-URL: `** `MANAGE_SERVER_URL` ist keine gültige URL. Sie muss mit `https://` beginnen und darf weder `/api` noch einen Schrägstrich am Ende enthalten. **`Authentifizierung fehlgeschlagen. (HTTP 401)`** Instanz-Kennung oder Token stimmen nicht. Beides ist absichtlich nicht unterscheidbar. Im Manage-Server unter **Instanzen** ein neues Token erzeugen und eintragen; das alte wird dabei sofort ungültig. **`Diese Instanz ist deaktiviert. (HTTP 403)`** Die Instanz existiert, ist aber im Manage-Server deaktiviert. Dort wieder aktivieren. **`Zu viele Anfragen. Bitte später erneut versuchen. (HTTP 429)`** Zu viele fehlgeschlagene Authentifizierungen von dieser IP. Nach Ablauf des Zeitfensters (Standard 5 Minuten) mit korrektem Token erneut versuchen. **`Antwort des Servers ist kein gültiges JSON.`** Die Antwort kam nicht vom Manage-Server: meist eine Fehlerseite des Webservers, eine Umleitung oder ein Captive Portal. Antwort direkt mit `curl` ansehen. ## Update **`Es ist kein neueres Update verfügbar. Mit der Option "force" kann dasselbe Paket erneut ausgerollt werden.`** Kein Fehler. Auf der Kommandozeile `update --force`, in der Oberfläche das Häkchen "erneut ausrollen". **`Version im Manifest ist ungültig.` / `Prüfsumme im Manifest ist ungültig.` / `Paket-URL im Manifest ist ungültig.`** Der Server liefert ein unbrauchbares Manifest. Auf dem Server prüfen, ob ein Release veröffentlicht und als aktuell gesetzt ist. Bei "Paket-URL ungültig" ist meist `MANAGE_PUBLIC_URL` in der Serverkonfiguration nicht oder falsch gesetzt. **`Größe des heruntergeladenen Pakets stimmt nicht überein.` / `Prüfsumme des Pakets stimmt nicht überein.`** Das Paket entspricht nicht dem Manifest. Die heruntergeladene Datei wird sofort gelöscht und **nichts** ausgerollt. Ursachen: abgebrochener Download, ein Proxy der den Inhalt verändert, oder ein auf dem Server ausgetauschtes Paket. Release neu hochladen und erneut versuchen. Wiederholt sich der Fehler, ist die Übertragungskette zu prüfen, bevor ausgerollt wird. **`Das heruntergeladene Paket ist keine lesbare ZIP-Datei.`** Die Datei ist beschädigt oder es wurde etwas anderes als ein ZIP hochgeladen. **`Das Paket enthält einen unsicheren Pfad: `** Ein Eintrag versucht aus dem Zielverzeichnis auszubrechen (`..`, absoluter Pfad, Laufwerksbuchstabe, Nullbyte). Es wird nichts entpackt. Ein solches Paket darf nicht ausgerollt werden – Herkunft klären. **`Das Paket sieht nicht wie ein Release dieser Anwendung aus (erwartet: index.php)`** Keiner der Pfade aus `MANAGE_UPDATE_SANITY_PATHS` ist im Paket. Fast immer wurde das ZIP mit einem Oberverzeichnis gebaut. Siehe [06_UPDATE_PACKAGING](06_UPDATE_PACKAGING.md). **`Die PHP-Erweiterung ZipArchive ist nicht verfügbar.`** `ext-zip` fehlt. Updates brauchen sie; Backups funktionieren auch ohne, weil der Client dort einen eigenen ZIP-Writer verwendet. Beim Hoster aktivieren lassen. **`Datei konnte nicht ausgerollt werden: ` / `Datei konnte nicht gesichert werden: `** Fehlende Schreibrechte im Anwendungsstamm. **Wichtig:** Dieser Fehler tritt mittendrin auf, das Ausrollen ist dann unvollständig. Rechte korrigieren und `update --force` erneut ausführen – der Lauf beginnt von vorn und stellt den vollständigen Zustand her. **`Verzeichnis konnte nicht erstellt werden: `** Fehlende Schreibrechte auf dem übergeordneten Verzeichnis. **`Altes Backup-Verzeichnis konnte nicht entfernt werden: `** Das Ausrollen war erfolgreich, nur das Aufräumen alter Sicherungen scheiterte. Verzeichnis von Hand entfernen. **`MANAGE_APP_ROOT existiert nicht: `** Der konfigurierte Anwendungsstamm ist falsch. Standard ist das Elternverzeichnis von `manage-client/`. ## Migrationen und Hook **`Migration liefert keine Funktion zurück und definiert kein up().`** Die Migrationsdatei muss entweder eine Funktion zurückgeben (`return function (array $context) {...};`) oder eine Funktion `up(array $context)` definieren. **Migration schlägt mit einem eigenen Fehler fehl** Der Lauf stoppt, die folgenden Migrationen bleiben offen, die Dateien sind aber bereits ausgerollt. Ursache beheben, dann: ```bash php manage-client/bin/manage-client.php migrate --dry-run php manage-client/bin/manage-client.php migrate ``` **`Hook-Datei wurde nicht gefunden: ` / `Hook-Callback ist nicht aufrufbar: `** `MANAGE_UPDATE_POST_HOOK` verweist auf eine fehlende Datei oder eine Funktion, die dort nicht definiert wird. Häufig, wenn die Hook-Datei nicht im Release-Paket liegt. **`Post-Update-Hook meldet einen Fehler`** Der Callback hat `false` oder `["success" => false]` zurückgegeben. Die Dateien sind ausgerollt; die Details stehen im Protokoll. ## Backup **`Es läuft bereits ein Backup.`** Die Sperrdatei ist belegt: ein zweiter Lauf startete, während der erste noch lief. Meist überlappen Cron-Job und manueller Aufruf. Warten und erneut versuchen. Bleibt es dauerhaft, wurde ein früherer Lauf hart abgebrochen – die Sperre löst sich mit dem Prozessende von selbst; hilft das nicht, `data/manage/backups/.backup.lock` entfernen, wenn sicher kein Backup läuft. **`Keine Dateien für das Backup gefunden.` / `Keine lesbaren Dateien für das Backup gefunden.`** `MANAGE_BACKUP_SOURCES` trifft auf keine existierende Datei. Pfade sind relativ zu `MANAGE_APP_ROOT`. Prüfen mit: ```bash php -r 'require "manage-client/lib/client.php"; print_r(manageBackupCollectSources());' ``` **`Backup-ZIP konnte nicht erstellt werden.` / `Backup-ZIP konnte nicht finalisiert werden.`** Keine Schreibrechte auf `MANAGE_BACKUP_DIR` oder die Festplatte ist voll. **`Datei ist zu groß für dieses Backup-Format: ` / `Backup-ZIP ist zu groß für dieses Backup-Format.` / `Zu viele Dateien für dieses Backup-Format.`** Grenzen des ZIP-Formats ohne Zip64: 4 GB pro Datei, 4 GB pro Archiv, 65535 Einträge. Quellen aufteilen oder große Mediendateien getrennt sichern. **`Ungültiger Pfad im Backup: ` / `Pfad im Backup ist zu lang: `** Ein Dateiname enthält ungültige Zeichen oder das `as`-Präfix erzeugt einen ungültigen Archivpfad. Präfixe ohne führenden Schrägstrich und ohne `..` verwenden. **`Der Manage-Server hat das Backup abgelehnt: Ungültiger Backup-Dateiname.`** Der Dateiname entspricht nicht `backup-YYYYmmdd-HHMMSS[-N].zip`. Tritt nur bei selbst gebauten Uploads auf. **`Der Manage-Server hat das Backup abgelehnt: Prüfsumme des Backups stimmt nicht überein.`** Das Archiv wurde unterwegs verändert oder unvollständig übertragen. Die Datei wird serverseitig gelöscht. Das lokale Archiv ist in Ordnung; erneut versuchen. **`Backup überschreitet das Upload-Limit des Servers (upload_max_filesize / post_max_size).`** Die PHP-Grenzen auf dem **Manage-Server** sind kleiner als das Archiv. Dort `upload_max_filesize` und `post_max_size` erhöhen (beide!) oder den Backup-Umfang reduzieren. Die aktuellen Werte stehen im Manage-Server unter **Einstellungen → Diagnose**. Der Upload-Fehler macht das lokale Archiv nicht ungültig – es liegt vollständig in `data/manage/backups/`. ## Datenbank **`Die PHP-PDO-Erweiterung ist nicht verfügbar.`** `pdo_mysql` fehlt. Ohne sie kann kein Dump erstellt werden; `MANAGE_BACKUP_DATABASE` auf `null` setzen oder die Erweiterung aktivieren lassen. **`Datenbankverbindung fehlgeschlagen: `** DSN, Benutzer oder Passwort stimmen nicht, oder der Server ist nicht erreichbar. Die Originalmeldung von PDO steht dahinter. **`MANAGE_BACKUP_DATABASE benötigt einen DSN.`** Das Array ist gesetzt, aber `dsn` fehlt oder ist leer. **`Datenbank-Dump fehlgeschlagen: `** Meist fehlende Rechte: Der Benutzer braucht `SELECT` und `SHOW VIEW` auf allen Tabellen. Der unvollständige Dump wird gelöscht, das Backup bricht ab. ## Zusätzliche Ziele **`Die PHP-SSH2-Erweiterung ist nicht verfügbar.`** SFTP braucht `ext-ssh2`. Ohne sie schlägt nur dieses Ziel fehl; das lokale Archiv und alle anderen Ziele bleiben davon unberührt. **`SFTP-Zieldatei konnte nicht geöffnet werden. Existiert das Verzeichnis?`** Das entfernte Verzeichnis muss vorhanden und beschreibbar sein; es wird nicht angelegt. **`S3-Ziel ist unvollständig konfiguriert.`** `bucket`, `region`, `access_key` und `secret_key` sind alle Pflicht. **`S3-Upload fehlgeschlagen (HTTP 403)`** Bei `SignatureDoesNotMatch` stimmen Region oder Secret Key nicht. Bei `AccessDenied` passt meist die Adressierungsart nicht – für S3-kompatible Anbieter `endpoint` setzen. **`Unbekannter Backup-Zieltyp: `** `type` muss `s3`, `sftp` oder `custom` sein. Der frühere Typ `managed` entfällt: Der Upload zum Manage-Server ist eingebaut und wird über `MANAGE_BACKUP_UPLOAD` gesteuert. ## Rechte auf einen Blick ```bash # Schreibrechte für PHP prüfen php -r ' foreach (["data/manage/backups", "data/manage/work", "data/manage/updates", "."] as $d) { printf("%-26s %s\n", $d, is_writable($d) ? "beschreibbar" : "NICHT beschreibbar"); }' ``` Der letzte Eintrag `.` ist der Anwendungsstamm – ohne Schreibrecht dort sind keine Updates möglich. ## Weiter - [03_CONFIG_REFERENCE](03_CONFIG_REFERENCE.md) – alle Konstanten - [08_PROTOCOL](08_PROTOCOL.md) – Anfragen mit `curl` nachstellen