diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index a29a7a9e5..1ce922551 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -1268,6 +1268,15 @@ func (m *Monitor) pollVMs(ctx context.Context, instanceName string, client PVECl func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, client PVEClientInterface, nodes []proxmox.Node) { var allVMs []models.VM for _, node := range nodes { + // Skip offline nodes to avoid 595 errors when trying to access their resources + if node.Status != "online" { + log.Debug(). + Str("node", node.Node). + Str("status", node.Status). + Msg("Skipping offline node for VM polling") + continue + } + vms, err := client.GetVMs(ctx, node.Node) if err != nil { monErr := errors.NewMonitorError(errors.ErrorTypeAPI, "get_vms", instanceName, err).WithNode(node.Node) @@ -1579,6 +1588,15 @@ func (m *Monitor) pollContainersWithNodes(ctx context.Context, instanceName stri var allContainers []models.Container for _, node := range nodes { + // Skip offline nodes to avoid 595 errors when trying to access their resources + if node.Status != "online" { + log.Debug(). + Str("node", node.Node). + Str("status", node.Status). + Msg("Skipping offline node for container polling") + continue + } + containers, err := client.GetContainers(ctx, node.Node) if err != nil { monErr := errors.NewMonitorError(errors.ErrorTypeAPI, "get_containers", instanceName, err).WithNode(node.Node) diff --git a/pkg/proxmox/client.go b/pkg/proxmox/client.go index 7038bbb5e..fdb76bb0a 100644 --- a/pkg/proxmox/client.go +++ b/pkg/proxmox/client.go @@ -268,8 +268,14 @@ func (c *Client) request(ctx context.Context, method, path string, data url.Valu // Special case for 403 with API token - this is usually a permission issue err = fmt.Errorf("API error 403 (Forbidden): The API token does not have sufficient permissions. Note: In Proxmox GUI, permissions must be set on the USER (not just the token). Please verify the user '%s@%s' has the required permissions", c.auth.user, c.auth.realm) } else if resp.StatusCode == 595 { - // 595 is Proxmox "no ticket" error - usually means authentication failed - err = fmt.Errorf("API error 595: Authentication failed - please check your credentials") + // 595 can mean authentication failed OR trying to access an offline node in a cluster + // Check if this is a node-specific endpoint + if strings.Contains(req.URL.Path, "/nodes/") && strings.Count(req.URL.Path, "/") > 3 { + // This looks like a node-specific resource request + err = fmt.Errorf("API error 595: Cannot access node resource - node may be offline or credentials may be invalid") + } else { + err = fmt.Errorf("API error 595: Authentication failed - please check your credentials") + } } else if resp.StatusCode == 401 { err = fmt.Errorf("API error 401 (Unauthorized): Invalid credentials or token") } else {