amir20/dozzle · error
cloud: alerts
Error message
cloud: alerts: %w
What it means
GetAlerts calls the cloud gRPC service (ListAlerts-style request with time range, limit, and include flags) and wraps any RPC failure with 'cloud: alerts: %w'. The cloud backend is unreachable, rejected the request, or returned an error. The wrapper preserves the underlying gRPC status for inspection.
Solutions
- Read the wrapped error with errors.Is/errors.As to check the gRPC status code
- Verify network connectivity and DNS for the cloud endpoint
- Confirm the cloud API key is valid and the account has an active pro plan (PermissionDenied stops retries)
- Retry with backoff; the cloud client already reconnects with exponential backoff for transient failures
Defensive patterns
Strategy: retry
Try / catch
hits, err := client.GetAlerts(ctx, req)
if err != nil {
if status.Code(err) == codes.PermissionDenied {
return nil, err // do not retry: invalid API key / no pro plan
}
return nil, fmt.Errorf("fetching alerts, will retry: %w", err)
} Prevention
- Check cloud endpoint health before heavy usage
- Keep the API key valid and the pro plan active
- Use context timeouts so failures surface quickly
- Distinguish PermissionDenied (permanent) from transient codes before retrying
When it happens
Trigger: Calling GetAlerts while the unary cloud connection fails: network outage, invalid API key returning PermissionDenied, server-side error, or context deadline exceeded during the RPC.
Common situations: Dozzle Cloud endpoint down or unreachable, expired/billing-deactivated API key, firewall blocking egress to the cloud service, timeouts on slow responses.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/26449ca295a5199f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloud/alerts.go:118
}
mdPairs := []string{"x-api-key", apiKey}
if c.instanceID != "" {
mdPairs = append(mdPairs, "x-instance-id", c.instanceID)
}
callCtx := metadata.NewOutgoingContext(ctx, metadata.Pairs(mdPairs...))
resp, err := client.GetAlerts(callCtx, &pb.GetAlertsRequest{
ContainerIds: containerIDs,
HostId: hostID,
FromTsNs: fromNs,
ToTsNs: toNs,
Limit: limit,
IncludeFollowUps: includeFollowUps,
IncludeEvents: includeEvents,
})
if err != nil {
return nil, fmt.Errorf("cloud: alerts: %w", err)
}
hits := make([]AlertHit, 0, len(resp.GetHits()))
for _, h := range resp.GetHits() {
hits = append(hits, AlertHit{
AlertID: h.GetAlertId(),
ContainerID: h.GetContainerId(),
HostID: h.GetHostId(),
LogID: h.GetLogId(),
Ts: h.GetAnchorTsNs(),
Headline: h.GetHeadline(),
Level: h.GetLevel(),
EventCount: h.GetEventCount(),
SuppressedCount: h.GetSuppressedCount(),
ContainerCount: h.GetContainerCount(),
Summary: h.GetSummary(),
Investigation: h.GetInvestigation(),
TriageAction: h.GetTriageAction(),View on GitHub (pinned to d9463cbe21)