Improve guest agent error classification to prevent false permission errors

Related to #596

**Problem:**
Users were seeing persistent "permission denied" error messages for VMs
that simply didn't have qemu-guest-agent installed or running. The error
detection logic was too broad and classified Proxmox API 500 errors as
permission issues, even when they indicated guest agent unavailability.

**Root Cause:**
When qemu-guest-agent is not installed or not running, Proxmox API returns
various error responses (500, 403) that may contain permission-related text.
The previous error detection logic checked for "permission denied" strings
without considering the HTTP status code context, leading to:
- VMs with guest agent: guest details display correctly
- VMs without guest agent: false "Permission denied" error shown

**Solution:**
Enhanced error classification logic to distinguish between:
1. Actual permission issues (401/403 with permission keywords)
2. Guest agent unavailability (500 errors)
3. Agent timeout issues
4. Other agent errors

The fix ensures that only explicit authentication/authorization errors
(401 Unauthorized, 403 Forbidden with permission keywords) are classified
as permission-denied, while API 500 errors are correctly identified as
agent-not-running issues.

**Changes:**
- Reordered error detection to check most specific patterns first
- Added HTTP status code context to permission error detection
- 500 errors now correctly map to "agent-not-running" status
- Only 401/403 errors with explicit permission keywords trigger "permission-denied"
- Improved log messages to guide users toward correct resolution
- Fixed err.Error() vs errStr variable inconsistency

**Impact:**
Users will now see accurate error messages that guide them to:
- Install qemu-guest-agent when it's missing (most common case)
- Check permissions only when there's an actual auth/authz issue
- Understand the difference between agent problems and permission problems
This commit is contained in:
rcourtman 2025-11-05 19:21:58 +00:00
parent ddc787418b
commit f0088070be

View file

@ -513,6 +513,8 @@ func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, cli
Str("error", errStr).
Msg("Failed to get VM filesystem info from guest agent")
// Classify the error type for better user messaging
// Order matters: check most specific patterns first
if strings.Contains(errStr, "QEMU guest agent is not running") {
diskStatusReason = "agent-not-running"
log.Info().
@ -520,10 +522,36 @@ func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, cli
Str("vm", vm.Name).
Int("vmid", vm.VMID).
Msg("Guest agent enabled in VM config but not running inside guest OS. Install and start qemu-guest-agent in the VM")
} else if strings.Contains(err.Error(), "timeout") {
} else if strings.Contains(errStr, "timeout") {
diskStatusReason = "agent-timeout"
} else if strings.Contains(err.Error(), "permission denied") || strings.Contains(err.Error(), "not allowed") {
} else if strings.Contains(errStr, "500") && (strings.Contains(errStr, "not running") || strings.Contains(errStr, "not available")) {
// Proxmox API error 500 with "not running"/"not available" indicates guest agent issue, not permissions
// This commonly happens when guest agent is not installed or not running
diskStatusReason = "agent-not-running"
log.Info().
Str("instance", instanceName).
Str("vm", vm.Name).
Int("vmid", vm.VMID).
Msg("Guest agent communication failed (API error 500). Install and start qemu-guest-agent in the VM")
} else if (strings.Contains(errStr, "403") || strings.Contains(errStr, "401")) &&
(strings.Contains(strings.ToLower(errStr), "permission") || strings.Contains(strings.ToLower(errStr), "forbidden") || strings.Contains(strings.ToLower(errStr), "not allowed")) {
// Only treat as permission-denied if we get explicit auth/permission error codes (401/403)
// This distinguishes actual permission issues from guest agent unavailability
diskStatusReason = "permission-denied"
log.Warn().
Str("instance", instanceName).
Str("vm", vm.Name).
Int("vmid", vm.VMID).
Msg("Permission denied accessing guest agent. Verify Pulse user has VM.Monitor (PVE 8) or VM.Audit+VM.GuestAgent.Audit (PVE 9) permissions")
} else if strings.Contains(errStr, "500") {
// Generic 500 error without clear indicators - likely agent unavailable
// Refs #596: Proxmox returns 500 errors when guest agent isn't installed/running
diskStatusReason = "agent-not-running"
log.Info().
Str("instance", instanceName).
Str("vm", vm.Name).
Int("vmid", vm.VMID).
Msg("Failed to communicate with guest agent (API error 500). This usually means qemu-guest-agent is not installed or not running in the VM")
} else {
diskStatusReason = "agent-error"
}