- Added debug mode: localStorage.setItem('debug-pmg', 'true')
- Robust VMID=0 detection handles string and number types
- Debug logging shows exactly what's happening with PMG backups
- Created test suite that verifies all PMG backup scenarios
- All test cases pass including PBS 'ct' type with VMID='0'
Users experiencing issues can enable debug mode to help diagnose:
1. Open browser console
2. Run: localStorage.setItem('debug-pmg', 'true')
3. Reload page and check for [PMG Debug] messages
4. Share debug output if still showing as LXC
Test results:
✓ PBS PMG backup (ct type with VMID 0) → Host
✓ PBS PMG backup (ct type with numeric VMID 0) → Host
✓ Storage PMG backup (host type) → Host
✓ Storage PMG backup (lxc type with VMID 0) → Host
✓ Regular LXC backup → LXC
- Add PULSE_ENABLE_ZFS_MONITORING env var (disabled by default)
- Fix API field mapping (health vs state, cksum vs checksum)
- Add proper API endpoint structures for list and detail
- Mark feature as experimental due to API complexity
- Simplify conversion to handle basic health status only
This is a safer approach until we can fully test with real Proxmox nodes
- Add ZFS pool status data structures to models
- Implement ZFS pool data collection via Proxmox API
- Add ZFS pool health alerts for degraded/faulted states
- Add ZFS device error detection and alerting
- Display ZFS pool status in Storage tab when issues detected
- Add mock data generation for testing ZFS monitoring
- Alert on read/write/checksum errors for pools and devices
The real issue was not the overall timeout duration, but that DNS resolution and TLS handshake could hang indefinitely. Added specific timeouts for:
- DNS resolution/connection: 10 seconds
- TLS handshake: 10 seconds
- Response headers: 10 seconds
This prevents the connection from hanging on DNS lookup (like with pve-backup.lan) or during TLS negotiation, which was causing the 'context deadline exceeded' errors. (addresses #424)
PBS servers can be slow to respond, especially under load or over slower connections. Increased the timeout from 10 seconds to 30 seconds specifically for PBS version checks during diagnostics.
- Reduced storage API timeout from 120s to 15s to prevent blocking when storage mounts are unavailable
- Added graceful error handling for storage timeouts - continues with partial data instead of failing
- Improved error messages to clarify when timeouts are likely due to unavailable storage (e.g., NFS mounts)
This prevents Pulse from marking nodes as unhealthy when storage endpoints timeout due to temporarily unavailable network storage.
- Use main host for cluster operations when node endpoints lack FQDNs/IPs
- Skip initial health check for single-endpoint clusters (main host routing)
- Return empty lists instead of errors when cluster nodes are unreachable
- Prevent VMs/containers from disappearing when cluster has connectivity issues
- Fix the 'Instance marked as cluster but is actually standalone' false warning
The /api/state and /api/guests/metadata endpoints are now excluded from
rate limiting as they are polled frequently by the UI for real-time updates.
This prevents the "Loading..." issue when users with multiple nodes access
the application.
- Added skip list in UniversalRateLimitMiddleware for real-time endpoints
- Removed duplicate rate limiting logic from router's ServeHTTP
- Consolidated all rate limiting into the universal middleware
The password change endpoint now handles both scenarios:
- Direct auth: Uses Authorization header when it contains Pulse credentials
- Proxy auth: Uses currentPassword from JSON body when behind proxy Basic Auth
- Prevents proxy auth from interfering with Pulse's own authentication
- Maintains security by always requiring current password verification
- Fixed undefined 'alert' variable in sendWebhookRequest function
- Dynamic ntfy headers are properly handled in sendWebhook where alert exists
- Cleared corrupted webhooks.enc file
- Webhook testing should now work without JSON parsing errors
- Fixed SendEnhancedWebhook to use service-specific payload generation
- Test webhooks now properly skip template-syntax headers
- ntfy and other plain text services correctly skip JSON validation
- Prevents 'invalid character' errors when testing webhooks
- All webhook payload generation now respects service type
- Replaced emoji indicators with plain text (CRITICAL, WARNING, INFO)
- Cleaned up ntfy, Gotify, and Telegram templates
- Removed decorative emojis from alert details
- Updated dynamic header generation to use plain text
- Maintains professional tone appropriate for monitoring software
- TestEnhancedWebhook now uses generatePayloadFromTemplateWithService to handle service-specific formatting
- ntfy webhooks correctly skip JSON validation since they use plain text
- Dynamic ntfy headers (Title, Priority, Tags) are properly set during testing
- Template-syntax headers with emojis no longer break webhook tests
- Fixes 'invalid character looking for beginning of value' error
- Fixed webhook ID extraction in UpdateWebhook and DeleteWebhook handlers
- Previous code expected 5 URL parts but path only had 2 after prefix stripping
- Now correctly extracts webhook ID from /api/notifications/webhooks/{id}
- Resolves frontend error when saving webhook changes
- ntfy template headers contained Go template syntax that wasn't being processed
- Added special handling for ntfy webhooks to set Title, Priority, and Tags dynamically
- Headers are now set based on actual alert level and details
- Ignores template-syntax headers from webhook config to prevent errors
- Fixes issue where ntfy webhooks with preset headers would fail to send
- Automatically detects the machine's IP address for webhook 'View in Pulse' links
- Checks multiple methods: Proxmox container, outbound IP, Docker, network interfaces
- Falls back through detection methods to find the best IP
- Users no longer need to manually set PULSE_PUBLIC_URL in most cases
- Manual configuration still takes precedence if set
PBS storage should respect Proxmox's shared configuration. When PBS
storage is configured without node restrictions in Proxmox, it appears
as shared storage accessible by all nodes. Updated mock data to match
real cluster behavior where PBS entries appear under 'cluster' group.
Mock data now accurately replicates production PBS storage where:
- Each node sees ALL PBS storage entries (pbs-pve1, pbs-pve2, pbs-pve3)
- Storage sizes and usage match production (~950GB, 14% used)
- Each PBS entry has a node-specific namespace but appears on all nodes
- PBS storage is correctly marked as not shared
Mock data now properly simulates PBS storage behavior where each node
reports all PBS namespaces (pbs-pve1, pbs-pve2, pbs-pve3). This accurately
replicates real cluster behavior where each node has access to all PBS
namespaces but they're node-specific and not shared.
PBS storage was being marked as shared when it shouldn't be. Each PBS
namespace is node-specific even when connecting to the same PBS server.
Now PBS storage correctly shows under its respective node instead of
all being assigned to the last node.
Mock cluster nodes now correctly show degraded state (yellow) when
some nodes are offline. This properly demonstrates the degraded cluster
functionality for issue #379.
Mock cluster endpoints were showing grey dots because the Online field
wasn't being set based on the node status. Now properly reflects the
node's online/offline status with green/grey indicators.
When some cluster nodes are offline but the main node can still reach others,
show a yellow status dot instead of red to indicate partial connectivity.
This better represents the actual cluster health state.
Added built-in Pushover template alongside Discord, Telegram, Gotify, and ntfy. Users can now select Pushover from the service dropdown instead of manually configuring it as a generic webhook.
PMG host configuration backups (VMID=0) are now correctly shown as "Host" type
in the backup list instead of being incorrectly labeled as "LXC" containers.
Also added mock data for testing VMID 0 host backups.
The acknowledge/unacknowledge/clear endpoints were returning 404 due to incorrect path trimming in HandleAlerts. The router was registered with /api/alerts/ but the handler was trimming /api/alerts, causing path parsing to be off by one character.
- Added migration to automatically enable MonitorBackups for PBS instances
- This fixes the issue where PBS backups weren't showing for some users
- The migration runs on startup and persists the changes
- All new PBS instances already have MonitorBackups enabled by default
- Added PULSE_PUBLIC_URL config option to specify the full URL to access Pulse
- Updated notification manager to use publicURL when constructing webhook payloads
- Modified prepareWebhookData to construct full URLs instead of just paths
- Fixed test webhooks to use configured publicURL instead of hardcoded values
- Gotify and ntfy notifications now include clickable links that work properly
- Windows System Reserved partitions now excluded from disk usage
- Added better handling for filesystems with zero total bytes
- Improved debug logging for skipped filesystems
- Prevents incorrect disk usage display for Windows VMs
- Added custom headers section to webhook configuration UI
- Users can now add, edit, and remove custom headers for authentication
- Updated ntfy instructions to be clearer about adding Authorization headers
- Supports Bearer tokens, API keys, and other custom headers
- Fixed shared storage jumping between nodes on each update by using consistent deduplication
- Shared storage now displays with node="cluster" to indicate it's cluster-wide
- Improved error logging when storage API calls fail to help diagnose permission issues
- Added specific warning when all nodes fail to retrieve storage (helps with #385, #411)
The jumping storage issue (#410) was caused by a race condition where parallel goroutines
would report shared storage under whichever node completed first, causing it to randomly
"jump" between nodes on each polling cycle.
- Added CheckStorage calls in parallel storage polling (was missing, causing storage alerts to not trigger)
- Fixed node cleanup logic to use alert.Node field directly instead of parsing IDs
- Removed auto-acknowledge on alert click - now only acknowledge button toggles state
- Added unacknowledge button for acknowledged alerts
- Fixed double-toggle issue with acknowledge button using race condition prevention
- Fixed tab menu width in Alerts and Settings pages (changed flex-shrink-0 to flex-1)
addresses #228 (storage alert threshold issue)
- Replace border-left with inset box-shadow for alert indicators
- Prevents unprofessional gaps between background and table edges
- Add alert support to NodeSummaryTable with same gap-free technique
- Generate offline alerts in mock data for testing
- Fix alert matching to use full resource ID for nodes
- Enable alert cooldown by default (5 minutes) to prevent notification spam
- Enable rate limiting by default (10 alerts/hour) to prevent flooding
- Enable smart grouping by default (30 second window, group by node)
- Keep quiet hours disabled by default (requires user configuration)
- Keep escalation disabled by default (requires user setup)
These defaults provide sensible protection against notification overload
while allowing users to opt-in to more advanced scheduling features
- Add dynamic metric fluctuations for VMs and containers in mock data
- Fix alert acknowledgment to dim instead of hide alerts
- Implement unacknowledge functionality with backend persistence
- Simplify alert UI to single-click toggle (remove selection system)
- Add proper hysteresis for alert resolution when metrics drop
- Fix SVG icon boundaries in alert displays
- Add webhook disable toggles for testing without notifications
- Fix frontend directory duplication issue (addresses frontend-modern recreation)
- Improve alert sorting to show most recent first
- Make mock system generate realistic metric changes for proper alert lifecycle
- Increased default HTTP client timeout from 30s to 60s
- Added CreateHTTPClientWithTimeout function to properly set custom timeouts
- Updated Proxmox and PBS clients to use configured timeout values
- Increased default connection timeout from 45s to 60s in config
This prevents "context deadline exceeded" errors when connecting to slow or overloaded Proxmox/PBS nodes.
- added color-coded emoji indicators (🔴/🟡/🟢) for alert levels
- enriched message formatting with better structure and emojis
- improved titles to show resource name and alert type clearly
- ntfy now has dynamic headers for priority and tags based on alert level
- both services now match the detail level of Discord and Telegram
- improved Gotify template to include resource name and node in message body
- changed title to show resource name instead of generic "Pulse Alert"
- added ntfy service option to frontend webhook configuration UI
- ntfy template was already in backend but missing from frontend selection
- Changed button type from 'button' to 'submit' so it actually submits the form
- This was the root cause - the button looked clickable but had no onClick handler
- Now the form properly submits when clicking Change Password
- Add DiskStatusReason field to track why disk stats are unavailable
- Show helpful tooltips in UI explaining specific issues:
- Proxmox 9 API token limitation (401 on guest agent endpoints)
- Guest agent not installed/running
- Special filesystems only (Live ISOs)
- Permission issues
- Add comprehensive troubleshooting guide (docs/VM_DISK_STATS_TROUBLESHOOTING.md)
- Document that API tokens cannot access guest agent data on PVE 9
- Tested and confirmed: only password/cookie auth works for guest agent on PVE 9
- Update README with quick reference to VM disk stats issue
This addresses issues #348, #367, and #71 by clearly explaining the root cause
(Proxmox API limitation) and providing actionable guidance to users.
- Ensure disk metrics from /nodes endpoint are preserved when GetNodeStatus fails
- Add better fallback logic to prevent showing 0% or '-' for disk usage
- Improve logging to distinguish between rootfs and /nodes endpoint metrics
- Handle cases where neither rootfs nor valid node disk data is available
This fixes the regression introduced in v4.12.1 where disk stats would show as
'-' when GetNodeStatus failed due to network issues or rate limiting