# Fehlerbehebung

Der schnellste Einstieg bei jedem Problem:

```powershell
python -m imapmig test -c meine.yaml -v
```

`-v` schaltet die ausführliche Protokollierung ein. Alles landet zusätzlich in der
Datei aus `options.log_file` (Vorgabe `migration.log`).

---

## Anmeldung am Zielpostfach

### `LOGIN failed` / `AUTHENTICATIONFAILED` bei `auth: basic`

Basic Authentication für IMAP und POP wurde in Exchange Online im Oktober 2022
abgeschaltet und Anfang Januar 2023 endgültig entfernt. Sie lässt sich nicht
reaktivieren.

**Abhilfe:** auf `auth: device`, `app` oder `password` wechseln – siehe
[entra-app-imap-user.md](entra-app-imap-user.md).

### `AADSTS7000218: The request body must contain client_assertion or client_secret`

Trotz der irreführenden Meldung fehlt hier meist der Schalter für öffentliche
Clientflows.

**Abhilfe:** App-Registrierung → **Authentifizierung** → *Erweiterte Einstellungen*
→ **„Öffentliche Clientflows zulassen" = Ja**.

### `AADSTS50076` / `AADSTS50079`: Multifaktor-Authentifizierung erforderlich

`auth: password` (ROPC) funktioniert grundsätzlich nicht mit MFA.

**Abhilfe:** `auth: device` verwenden. Der Benutzer meldet sich einmal im Browser an,
danach läuft alles unbeaufsichtigt weiter.

### `AADSTS65001`: Keine Zustimmung erteilt

**Abhilfe:** In der App unter **API-Berechtigungen** auf
**„Administratorzustimmung für <Organisation> erteilen"** klicken. In der Spalte
*Status* muss überall ein grüner Haken stehen.

### `AADSTS7000215`: Ungültiger Clientschlüssel

Meist wurde die **Geheimnis-ID** statt des **Werts** kopiert, oder der Schlüssel ist
abgelaufen.

**Abhilfe:** Neuen Schlüssel erzeugen und diesmal die Spalte *Wert* kopieren.

### `AADSTS500011`: Ressourcenprinzipal nicht gefunden

Die Berechtigung wurde unter der falschen API vergeben.

**Abhilfe:** Für IMAP muss sie unter **„Office 365 Exchange Online"** liegen, nicht
unter „Microsoft Graph". Für den Graph-Kanal genau umgekehrt.

### `AUTHENTICATE failed` bei `auth: app`, obwohl der Token kommt

Entra stellt den Token aus, Exchange Online lehnt ihn ab. Es fehlt die Freigabe auf
der Exchange-Seite.

**Abhilfe:** `New-ServicePrincipal` **und** `Add-MailboxPermission` ausführen –
Schritte 5 und 6 in [entra-app-imap-app.md](entra-app-imap-app.md). Beides ist
nötig, eines allein reicht nicht.

---

## IMAP im Zielpostfach

### Anmeldung gelingt, aber kein Ordner ist erreichbar

IMAP ist für das Postfach deaktiviert.

```powershell
Connect-ExchangeOnline
Get-CASMailbox -Identity ziel@ihredomain.de | Format-List Name,ImapEnabled
Set-CASMailbox  -Identity ziel@ihredomain.de -ImapEnabled $true
```

Für künftig angelegte Postfächer zusätzlich der Postfachplan:

```powershell
Get-CASMailboxPlan | Set-CASMailboxPlan -ImapEnabled $true
```

Änderungen brauchen bis zu 30 Minuten.

### Die Migration bricht nach etwa einer Stunde ab

Das sollte nicht passieren – das Werkzeug baut die Verbindung mit einem frischen
Token neu auf, wenn sie abreißt. Tritt es doch auf, hilft `-v` beim Eingrenzen. Der
Lauf ist wiederaufnehmbar: einfach denselben Befehl erneut starten, es geht dort
weiter, wo er stehen geblieben ist.

---

## Quellserver

### `Verbindung zu ... fehlgeschlagen: [SSL: CERTIFICATE_VERIFY_FAILED]`

Der Quellserver hat ein selbstsigniertes oder abgelaufenes Zertifikat.

```yaml
source:
  verify_cert: false
```

Das schaltet die Prüfung ab und macht die Verbindung angreifbar. Nur in einem
kontrollierten Netz und nur, wenn Sie den Server kennen.

### `[SSL: WRONG_VERSION_NUMBER]`

Es wird TLS auf einem Klartext-Port gesprochen (oder umgekehrt).

```yaml
source:
  ssl: true       # Port 993
  port: 993
```
oder
```yaml
source:
  ssl: false      # Port 143 mit STARTTLS
  starttls: true
  port: 143
```

### Ordnernamen mit Umlauten sehen falsch aus

IMAP kodiert Ordnernamen in modifiziertem UTF-7. Das Werkzeug dekodiert das
automatisch. Erscheinen trotzdem Zeichen wie `&APw-`, hält sich der Quellserver
nicht an den Standard – dann helfen feste Zuordnungen:

```yaml
options:
  folder_map:
    "INBOX.Entw&APw-rfe": "Entwürfe"
```

### Die Migration ist sehr langsam

Meist drosselt der Quellserver. Kleinere Bündel entlasten ihn:

```yaml
options:
  fetch_chunk: 5
```

Der Ordner „Alle Nachrichten" bei Gmail enthält jede Nachricht ein zweites Mal;
`skip_gmail_all_mail: true` (Vorgabe) überspringt ihn.

---

## Ordner und Nachrichten

### Ordner landen an der falschen Stelle

Erst ansehen, was passieren würde:

```powershell
python -m imapmig folders -c meine.yaml --count
```

Stellschrauben:

- `strip_inbox_prefix: true` – für Server, die alles unter `INBOX.` ablegen.
- `root_folder: Migration` – legt die komplette Struktur unter einen Zielordner.
- `folder_map` – feste Zuordnung, schlägt jede Automatik.

### Sonderordner werden nicht erkannt

Wenn der Quellserver kein SPECIAL-USE liefert und der Ordner ungewöhnlich heißt,
greift die Namensheuristik nicht.

```yaml
options:
  folder_map:
    "Verschickt": "Sent Items"
    "Ablage P": "Deleted Items"
```

Die Zielnamen zeigt `python -m imapmig test -c meine.yaml` in der Zeile
*Sonderordner*.

### Nachrichten sind doppelt angekommen

Fast immer, weil zwischen zwei Läufen die Fortschrittsdatenbank fehlte oder ein
anderer Pfad in `state_db` stand.

**Vorbeugen:** `state_db` unverändert lassen.
**Reparieren:** Die Dubletten müssen in Outlook entfernt werden – das Werkzeug löscht
grundsätzlich nichts im Zielpostfach. Für den nächsten Versuch:

```powershell
python -m imapmig run -c meine.yaml --dedupe-target
```

Damit werden die `Message-ID`s der Zielordner vorab gelesen und Vorhandenes
übersprungen.

### Einzelne Nachrichten wurden übersprungen

```powershell
python -m imapmig status --state-db state.sqlite3 --errors 50
```

Typische Gründe:

- **Größe.** Über `options.max_size_mb` (Vorgabe 35 MB). Exchange Online nimmt
  standardmäßig nicht mehr an; erlaubt Ihre Organisation mehr, setzen Sie den Wert
  hoch.
- **Graph-Grenze.** Rund 3 MB je Nachricht. `graph_imap_fallback: true` setzen oder
  `channel: imap` verwenden.
- **Dublette.** Bei `--dedupe-target` bereits im Ziel vorhanden.

Fehlgeschlagene (nicht übersprungene) Nachrichten erneut versuchen:

```powershell
python -m imapmig run -c meine.yaml --retry-errors
```

### `UIDVALIDITY geändert, Ordnerstatus wird verworfen`

Der Quellserver hat die Ordnerkennung neu vergeben – nach einer Wiederherstellung
oder einem Serverumzug. Die bisherigen UIDs sind damit wertlos.

Der Ordner wird komplett neu übertragen. Um Dubletten zu vermeiden, in diesem Fall
einmal mit `--dedupe-target` laufen lassen.

---

## Microsoft Graph

### HTTP 429 im Protokoll

Normale Drosselung durch Exchange Online. Das Werkzeug wertet `Retry-After` aus und
macht selbstständig weiter. Bei sehr vielen 429-Meldungen lohnt der Wechsel auf
`channel: imap`.

### `ErrorAccessDenied`

Die Anwendungszugriffsrichtlinie schließt das Postfach aus:

```powershell
Test-ApplicationAccessPolicy -Identity ziel@ihredomain.de -AppId "<client_id>"
```

Neue Richtlinien brauchen bis zu einer Stunde.

### `MailboxNotEnabledForRESTAPI`

Das Postfach liegt lokal (Hybridbereitstellung) oder ist ein nicht unterstützter
Typ. Graph erreicht nur Postfächer in Exchange Online.

---

## Weboberfläche

### „Zugriff verweigert"

Die URL wurde ohne Token aufgerufen. Die vollständige Adresse steht beim Start im
Terminal:

```
http://127.0.0.1:8765/?token=...
```

Bei jedem Neustart wird ein neues Token erzeugt.

### „Es läuft bereits eine Migration"

Es kann immer nur ein Auftrag gleichzeitig laufen. Entweder auf **Stoppen** klicken
oder das Ende abwarten.

### Der Anmeldecode erscheint nicht

Der Code wird erst angezeigt, wenn der Auftrag läuft und die Anmeldung ansteht.
Er steht immer auch im Terminal, in dem `python -m imapmig web` läuft.

---

## Wenn nichts hilft

```powershell
python -m imapmig run -c meine.yaml -v
```

Das Protokoll aus `migration.log` enthält den vollständigen Verlauf. Passwörter und
Token stehen nicht darin, Server- und Postfachnamen schon – vor dem Weitergeben
also durchsehen.
