{"record":{"id":"11035a5b42a855e5","repo":"amir20/dozzle","slug":"failed-to-exchange-token","errorCode":null,"errorMessage":"failed to exchange token","messagePattern":"failed to exchange token","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/web/cloud.go","lineNumber":74,"sourceCode":"\n\texchangeURL := fmt.Sprintf(\"%s/api/exchange-token\", cloudURL)\n\n\tclient := cloudHTTPClient\n\treq, err := http.NewRequestWithContext(r.Context(), http.MethodPost, exchangeURL, nil)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"Failed to create request\")\n\t\thttp.Error(w, \"failed to create request\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\treq.Header.Set(\"User-Agent\", dispatcher.UserAgent)\n\tq := req.URL.Query()\n\tq.Set(\"token\", token)\n\treq.URL.RawQuery = q.Encode()\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"Failed to exchange token\")\n\t\thttp.Error(w, \"failed to exchange token\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))\n\t\tlog.Error().Int(\"status\", resp.StatusCode).Str(\"body\", string(body)).Msg(\"Token exchange failed\")\n\t\thttp.Error(w, \"token exchange failed\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tvar tokenResp exchangeTokenResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {\n\t\tlog.Error().Err(err).Msg(\"Failed to decode token response\")\n\t\thttp.Error(w, \"failed to decode token response\", http.StatusInternalServerError)\n\t\treturn\n\t}\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/web/cloud.go#L56-L92","documentation":"After building the token-exchange request, cloudCallback executes it with the shared cloud HTTP client. Any transport-level failure (DNS, TCP connect, TLS, timeout, context cancellation) results in a 500 with this message. The underlying error is logged with `Failed to exchange token`.","triggerScenarios":"The POST to `{cloudURL}/api/exchange-token` fails at transport level: cloud service unreachable, DNS failure, TLS error, network outage, or the request context was cancelled because the user aborted the callback request.","commonSituations":"DOLIGENCE_URL points at an internal/self-hosted endpoint that is down or unreachable from the dozzle container; firewall blocks egress; DNS misconfiguration; corporate proxy required but not configured.","solutions":["Verify the cloud endpoint is reachable from the dozzle host (curl the /api/exchange-token URL).","Check DNS and outbound firewall/proxy settings for the dozzle container.","If using a custom DOLIGENCE_URL, confirm the service is running and the scheme/host are correct.","Retry the cloud connect flow in case of a transient network failure."],"exampleFix":"// before\ncurl: (6) Could not resolve host: doligence.internal\n// after\nDOLIGENCE_URL=https://doligence.dozzle.dev  # reachable default endpoint","handlingStrategy":"retry","validationCode":"curl -fsS -X POST \"${DOLIGENCE_URL:-https://doligence.dozzle.dev}/api/exchange-token?token=test\" -o /dev/null && echo reachable","typeGuard":null,"tryCatchPattern":"try {\n  await connectCloud();\n} catch (err) {\n  if (isNetworkError(err)) await retryWithBackoff(connectCloud);\n  else throw err;\n}","preventionTips":["Verify egress/DNS from the dozzle container before enabling cloud features.","Configure proxy variables if the environment requires an outbound proxy.","Retry the connect flow on transient failures."],"tags":["network","http-client","cloud"],"backgroundTag":"http-request-failed","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}