VM Tracker Client - FAQ & Troubleshooting¶
Table of Contents¶
- Installation & Deployment
- Network Issues
- Interface Detection
- API Server Connection
- Startup Errors
- Runtime Issues
- Performance & Resources
- Container & Orchestration
- Configuration
- Logging & Debugging
Installation Deployment¶
Q: Client won't start - "command not found"¶
Problem: When executing, bash: vm-tracker-client: command not found appears
Cause: - Binary is not in PATH - No execution permissions
Solution:
# Set execution permissions
chmod +x vm-tracker-client
# Execute with full path
./vm-tracker-client
# Or move to /usr/local/bin
sudo mv vm-tracker-client /usr/local/bin/
vm-tracker-client
Q: Build fails - "go: cannot find main module"¶
Problem: go build doesn't work
Cause: - Not in the correct directory - go.mod is missing
Solution:
# Change to the correct directory
cd vm-tracker-client/
# Create go.mod if not present
go mod init vm-tracker-client
# Execute build
go build -o vm-tracker-client main.go
Code Reference: go.mod:1-3
Q: Cross-compilation for other platforms?¶
Problem: Need to build binary for Linux but working on macOS
Solution:
# For Linux 64-bit
GOOS=linux GOARCH=amd64 go build -o vm-tracker-client-linux main.go
# For Windows
GOOS=windows GOARCH=amd64 go build -o vm-tracker-client.exe main.go
# For ARM (e.g., Raspberry Pi)
GOOS=linux GOARCH=arm64 go build -o vm-tracker-client-arm64 main.go
# For ARM 32-bit
GOOS=linux GOARCH=arm GOARM=7 go build -o vm-tracker-client-arm main.go
Network Issues¶
Q: "interface eth0 not found"¶
Problem:
Warning: interface eth0 not found: route ip+net: no such network interface, retrying in 5 seconds...
Cause: - Interface name is wrong (main.go:102) - Interface doesn't exist on the system - Interface names differ by OS
Diagnosis:
# Show all interfaces
ip addr show # Linux
ifconfig # macOS/BSD
ip link show # Alternative Linux
# Or with the client itself
go run main.go -interface "WRONG_NAME" 2>&1 | grep "interface"
Solution:
# Use correct interface name
./vm-tracker-client -interface "eth0" # Typical for Linux
./vm-tracker-client -interface "enp0s1" # Modern Linux systems
./vm-tracker-client -interface "en0" # macOS
./vm-tracker-client -interface "ens33" # VMware VMs
Common Interface Names:
| System | Typical Names |
|---|---|
| Ubuntu/Debian (old) | eth0, eth1, wlan0 |
| Ubuntu/Debian (new) | enp0s1, enp0s3, ens33 |
| CentOS/RHEL | eno1, ens192, enp0s3 |
| macOS | en0, en1 |
| Docker | eth0, docker0 |
| Kubernetes | eth0, cali* |
Code Reference: main.go:33-37
Q: "no IPv4 address found on interface"¶
Problem:
Cause: - Interface has no IPv4 address (main.go:46-55) - Interface is down - Only IPv6 configured - DHCP hasn't assigned an IP yet
Diagnosis:
# Check interface status
ip addr show eth0
ifconfig eth0
# Check if interface is UP
ip link show eth0 | grep "state UP"
Solution:
# Activate interface
sudo ip link set eth0 up
# Request DHCP IP
sudo dhclient eth0
# Set static IP (if needed)
sudo ip addr add 192.168.1.100/24 dev eth0
# Choose different interface
./vm-tracker-client -interface "eth1"
Workaround for IPv6-only systems: The client currently only supports IPv4. You must choose an interface with IPv4.
Code Reference: main.go:46-55
Q: Client can't find IP address with dynamic DHCP¶
Problem: During DHCP lease renewal, the client temporarily loses the IP
Cause: - Interface is briefly reconfigured - IP address changes - Race condition during DHCP renewal
Solution:
# Use shorter update interval
./vm-tracker-client -interval 10
# Longer retry delay for more stability
./vm-tracker-client -retry 10
# Use static IP (recommended for servers)
sudo ip addr add 192.168.1.100/24 dev eth0
Best Practice: For production VMs, it's recommended to use static IP addresses or DHCP reservations.
API Server Connection¶
Q: "Failed to register: connection refused"¶
Problem:
Failed to register: error sending request: Post "http://10.0.2.196:8080/api/register": dial tcp 10.0.2.196:8080: connect: connection refused
Cause: - API server is not running (main.go:80-82) - Wrong URL configured - Firewall blocking port 8080 - Network routing problem
Diagnosis:
# Test server reachability
ping 10.0.2.196
# Check port reachability
nc -zv 10.0.2.196 8080
telnet 10.0.2.196 8080
# Test with curl
curl -v http://10.0.2.196:8080/api/register
Solution:
# Use correct API URL
./vm-tracker-client -api "http://CORRECT_IP:8080"
# Check if API server is running
systemctl status vm-tracker-api
docker ps | grep vm-tracker-api
# Add firewall rule (server-side)
sudo ufw allow 8080/tcp
sudo firewall-cmd --add-port=8080/tcp --permanent
Code Reference: main.go:100, main.go:80-82
Q: "server returned status 404"¶
Problem:
Cause: - API endpoint doesn't exist (main.go:91-93) - Wrong API version - Server is misconfigured
Diagnosis:
# Test API endpoints
curl -v http://api-server:8080/api/register
# Check which endpoints are available
curl http://api-server:8080/
curl http://api-server:8080/health
Solution:
# Check API server logs
journalctl -u vm-tracker-api -n 50
# Restart API server
systemctl restart vm-tracker-api
# Ensure correct URL (without trailing slash)
./vm-tracker-client -api "http://api-server:8080"
Note: The client expects the endpoint /api/register (main.go:80)
Code Reference: main.go:80, main.go:91-93
Q: "server returned status 500"¶
Problem:
Cause: - Internal error in API server - Database connection failed - Invalid data in request
Diagnosis:
# Check API server logs
journalctl -u vm-tracker-api -f
docker logs vm-tracker-api --tail 100
# Test request manually
curl -X POST http://api-server:8080/api/register \
-H "Content-Type: application/json" \
-d '{"hostname":"test","ip_address":"192.168.1.1","interface":"eth0"}'
Solution: - Analyze server-side logs - Restart API server - Check database connection
Code Reference: main.go:91-93
Q: Timeouts on slow networks¶
Problem: Client hangs on slow network connections
Cause: - No timeouts configured (main.go:67) - Default HTTP client has very long timeouts
Solution:
Currently the client uses http.Post() without custom timeouts. For production environments, modification is recommended:
Workaround:
Improvement suggestion: Extend HTTP client with configurable timeout
Interface Detection¶
Q: Multiple IP addresses on one interface¶
Problem: Interface has multiple IPs, client takes the wrong one
Cause: - Code takes the first found IPv4 address (main.go:47-52) - No prioritization by IP type
Diagnosis:
# Show all IPs on interface
ip addr show eth0
# Example output:
# inet 192.168.1.100/24 ...
# inet 10.0.0.5/8 ...
Current behavior: The client returns the first non-loopback IPv4 address.
Solution: If a specific IP is needed, currently an interface must be chosen that only has that IP, or the code must be modified.
Code Reference: main.go:47-52
Q: VPN interfaces are detected instead of physical¶
Problem: Client registers VPN IP instead of server IP
Cause: - VPN interface is also named "eth0" - No distinction between interface types
Diagnosis:
Solution:
# Specify specific physical interface
./vm-tracker-client -interface "enp0s1" # Physical interface
# NOT: -interface "tun0" # VPN interface
Common VPN interface names (avoid): - tun0, tun1 (OpenVPN) - wg0 (WireGuard) - ppp0 (PPTP)
Q: Loopback interface is not detected (expected behavior)¶
Problem: ./vm-tracker-client -interface "lo" finds no IP
Cause: Loopback addresses are intentionally filtered (main.go:48)
Solution: This is intended behavior. Use a real network interface.
Code Reference: main.go:48
Startup Errors¶
Q: "Failed to register after 3 attempts, exiting"¶
Problem:
Failed to register: error sending request: ..., retrying in 5 seconds...
Failed to register: error sending request: ..., retrying in 5 seconds...
Failed to register: error sending request: ..., retrying in 5 seconds...
Failed to register after 3 attempts, exiting
Cause: - All 3 retry attempts failed (main.go:160-162) - API server not reachable - Network problem persistent
Diagnosis:
# Activate verbose mode for more details
./vm-tracker-client -verbose
# Check network connectivity
ping API_SERVER_IP
curl http://API_SERVER_IP:8080/api/register
Solution:
# Start/check API server
systemctl status vm-tracker-api
# Longer retry delay (more time for server start)
./vm-tracker-client -retry 10
# Fix network problems
# (Firewall, routing, etc.)
Note:
- Max. 3 retries are hardcoded (main.go:126)
- Retry delay is configurable via -retry flag
Code Reference: main.go:124-162
Q: Client starts too early (before network initialization)¶
Problem: Client starts at boot, but network is not ready yet
Cause: - Systemd/Init starts service too early - Network interface not configured yet
Solution for Systemd:
[Unit]
Description=VM Tracker Client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Additional delay
ExecStartPre=/bin/sleep 5
ExecStart=/usr/local/bin/vm-tracker-client -api "http://api:8080" -interface "eth0"
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Alternative: Use longer retry delay
Runtime Issues¶
Q: Client stops sending updates after some time¶
Problem: Initial registration successful, but then no more updates
Cause: - Network interruption - API server restarted - Errors are only logged, client continues (main.go:186-187)
Diagnosis:
# Check logs
journalctl -u vm-tracker-client -f
# Start with verbose mode
./vm-tracker-client -verbose
Behavior: In the main loop, errors are only logged, the client does not terminate (main.go:186-187):
if err := sendRegistration(*apiURL, info); err != nil {
log.Printf("Failed to send update: %v", err)
// Client continues!
}
Solution: This is expected behavior - the client will try again at the next interval.
Code Reference: main.go:186-187
Q: IP address changes, but old IP continues to be sent¶
Problem: DHCP renews IP, but client sends old IP
Cause: This should not happen, as the IP is retrieved each time (main.go:169):
Diagnosis:
# Check with verbose logging
./vm-tracker-client -verbose
# Output should show:
# Sending update: {Hostname:... IPAddress:NEW_IP Interface:eth0}
If problem persists:
# Restart client
systemctl restart vm-tracker-client
# Shorter update interval
./vm-tracker-client -interval 10
Code Reference: main.go:169
Q: Hostname changes to "unknown"¶
Problem: Hostname is suddenly registered as "unknown"
Cause:
- os.Hostname() fails (main.go:25-28)
- Hostname was changed on the system
- Permissions problem
Diagnosis:
Solution:
# Set hostname
sudo hostnamectl set-hostname my-server
# Check /etc/hostname
echo "my-server" | sudo tee /etc/hostname
# Restart client
systemctl restart vm-tracker-client
Code Reference: main.go:24-30
Q: Client consumes too many resources¶
Problem: High CPU or RAM usage
Cause: - Update interval too short - Memory leak (unlikely with this code) - Too many log entries
Diagnosis:
# Check resource usage
top -p $(pgrep vm-tracker-client)
ps aux | grep vm-tracker-client
# Memory profiling
go tool pprof http://localhost:6060/debug/pprof/heap
Solution:
# Longer interval
./vm-tracker-client -interval 300 # 5 minutes
# Disable verbose logging
./vm-tracker-client -verbose=false
# Limit logs (systemd)
journalctl --vacuum-time=7d
Expected usage: - CPU: < 1% idle - RAM: 5-10 MB
Performance Resources¶
Q: Too many log entries with problems¶
Problem: Log files become very large
Cause: - Errors are logged at every interval - Verbose mode activated - No log rotation
Solution:
1. Set up log rotation (logrotate):
# /etc/logrotate.d/vm-tracker-client
/var/log/vm-tracker-client.log {
daily
rotate 7
compress
missingok
notifempty
create 0644 root root
}
2. Limit systemd journal:
3. Verbose mode only when needed:
Q: Interval vs. network load¶
Problem: How do I balance update frequency and network load?
Recommendations:
| Scenario | Recommended Interval | Reasoning |
|---|---|---|
| Development/Testing | 10-30s | Fast feedback |
| Production VMs (stable) | 60-300s | Good balance |
| Low priority | 300-600s | Minimal load |
| Dynamic IPs (DHCP) | 30-60s | Timely updates |
| Static IPs | 300s+ | Rare changes |
Network load calculation:
Code Reference: main.go:104
Container Orchestration¶
Q: Docker container cannot find host interface¶
Problem:
Cause: - Container has its own network namespace - Host interfaces are not visible - Using wrong interface in container
Solution:
Option 1: Use host network
Option 2: Use container interface
# In container, the interface is normally "eth0"
docker run \
vm-tracker-client:latest \
-api "http://api:8080" \
-interface "eth0"
Option 3: Custom network
docker network create --driver bridge my-network
docker run --network my-network \
vm-tracker-client:latest \
-api "http://api:8080" \
-interface "eth0"
Q: Kubernetes pod cannot send VM information¶
Problem: Pod registers container IP instead of node IP
Cause: - Pod has its own network - hostNetwork not activated
Solution:
DaemonSet with hostNetwork:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: vm-tracker-client
spec:
selector:
matchLabels:
app: vm-tracker-client
template:
metadata:
labels:
app: vm-tracker-client
spec:
hostNetwork: true
containers:
- name: client
image: vm-tracker-client:latest
args:
- "-api"
- "http://vm-tracker-api:8080"
- "-interface"
- "eth0" # Host interface!
Important: hostNetwork: true is required for access to host interfaces
Q: Graceful shutdown doesn't work in container¶
Problem: Container stops hard, no clean termination
Cause: - Signal is not forwarded - Container doesn't run as PID 1 - Stop timeout too short
Solution:
Dockerfile:
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o vm-tracker-client main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/vm-tracker-client .
# Run binary as PID 1
ENTRYPOINT ["./vm-tracker-client"]
CMD ["-api", "http://api:8080", "-interface", "eth0"]
Docker Compose:
services:
client:
image: vm-tracker-client:latest
stop_grace_period: 30s # Enough time for shutdown
command: ["-api", "http://api:8080", "-interface", "eth0"]
Code Reference: main.go:117-119, main.go:192-194
Configuration¶
Q: Default API URL hardcoded in code¶
Problem: Default is http://10.0.2.196:8080 (main.go:100)
Cause: Developer-specific IP is hardcoded
Solution:
Option 1: Always use -api flag
Option 2: Environment variable (not supported) Currently the client doesn't support ENV variables.
Option 3: Create wrapper script
#!/bin/bash
# /usr/local/bin/vm-tracker-start.sh
API_URL="${API_URL:-http://production-api:8080}"
INTERFACE="${INTERFACE:-eth0}"
exec /usr/local/bin/vm-tracker-client \
-api "$API_URL" \
-interface "$INTERFACE" \
"$@"
Code Reference: main.go:100
Q: How can I persist configuration?¶
Problem: Don't want to specify all flags on every start
Solution:
Option 1: Systemd service
[Service]
ExecStart=/usr/local/bin/vm-tracker-client \
-api "http://api:8080" \
-interface "eth0" \
-interval 60 \
-verbose
Option 2: Wrapper script (see above)
Option 3: Config file (not supported) The client currently doesn't support config files. Extension possible with: - YAML/JSON config - Viper library - Environment variables
Q: Can I monitor multiple interfaces?¶
Problem: VM has multiple network interfaces
Answer: No, the client currently only supports one interface (main.go:102).
Workaround: Start multiple client instances:
# Instance 1
./vm-tracker-client -api "http://api:8080" -interface "eth0" &
# Instance 2
./vm-tracker-client -api "http://api:8080" -interface "eth1" &
Note: This sends separate registrations. The API server must be able to manage multiple IPs per hostname.
Logging Debugging¶
Q: How do I enable debug logging?¶
Solution:
# Verbose mode
./vm-tracker-client -verbose
# Redirect output
./vm-tracker-client -verbose > /var/log/vm-tracker.log 2>&1
# With systemd
journalctl -u vm-tracker-client -f
Verbose output shows: - Every registration request - Sent VMInfo data - Success confirmations
Code Reference: main.go:145-146, main.go:182-183, main.go:188-189
Q: No logs visible¶
Problem: Client is running, but no log output
Cause:
- Logs go to stdout/stderr
- systemd journal captures logs
- No errors = little output without -verbose
Solution:
# Systemd logs
journalctl -u vm-tracker-client -f
# Docker logs
docker logs -f container_name
# Kubernetes logs
kubectl logs -f pod_name
# File-based logging
./vm-tracker-client -verbose 2>&1 | tee /var/log/vm-tracker.log
Q: How can I debug HTTP requests?¶
Problem: Want to see exactly what is being sent
Solution:
Option 1: Verbose + tcpdump
# Terminal 1: Client with verbose
./vm-tracker-client -verbose -api "http://api:8080"
# Terminal 2: Capture traffic
sudo tcpdump -i eth0 -A 'tcp port 8080'
Option 2: Use proxy
# HTTP debugging proxy (mitmproxy)
mitmproxy -p 8888
# Client through proxy
HTTP_PROXY=http://localhost:8888 ./vm-tracker-client
Option 3: Code modification Log request body before sending (main.go:75-78):
Q: How to test without real API server?¶
Problem: Want to test client, but no API server available
Solution:
Option 1: Mock server with netcat
# Terminal 1: Mock server
while true; do
echo -e "HTTP/1.1 200 OK\r\n\r\nOK" | nc -l 8080
done
# Terminal 2: Client
./vm-tracker-client -api "http://localhost:8080"
Option 2: httpbin.org (for internet tests)
Option 3: Use unit tests
Code Reference: main_test.go:168-235
Advanced Troubleshooting¶
Q: Client sends wrong data¶
Problem: API server receives invalid or wrong data
Diagnosis:
# 1. Activate verbose mode
./vm-tracker-client -verbose
# 2. Check data in log
# Output should be:
# Sending registration: {Hostname:xyz IPAddress:192.168.1.100 Interface:eth0}
# 3. Check hostname manually
hostname
# 4. Check IP manually
ip addr show eth0 | grep "inet "
Possible causes:
- Hostname is "unknown" → os.Hostname() fails
- IP is wrong → Wrong interface
- Interface name wrong → Typo in parameter
Code Reference: main.go:139-143
Q: Memory leak during long-term operation?¶
Problem: Memory usage increases continuously
Diagnosis:
# Activate memory profiling
# (Requires code change for pprof server)
# Monitor resources
watch -n 5 'ps aux | grep vm-tracker-client'
# Go memory stats
GODEBUG=gctrace=1 ./vm-tracker-client
Expected behavior: - Constant memory usage (~5-10 MB) - No increase over time - Go garbage collector should run regularly
Possible causes: - HTTP response bodies not closed → Already fixed (main.go:85-89) - Ticker not stopped → Correctly handled (main.go:122)
Code Reference: main.go:85-89, main.go:122
Q: Race conditions on shutdown?¶
Problem: Errors when terminating the client
Diagnosis:
# Activate race detector
go run -race main.go -api "http://api:8080"
# Or during build
go build -race -o vm-tracker-client main.go
./vm-tracker-client
Shutdown sequence:
1. SIGTERM/SIGINT received (main.go:192)
2. Log message output (main.go:193)
3. return from main() (main.go:194)
4. defer ticker.Stop() is executed (main.go:122)
Code is race-free because: - Only one goroutine (main) - Channels are used correctly - Ticker is properly stopped
Code Reference: main.go:117-122, main.go:192-194
Performance Optimization¶
Q: How to optimize for high VM count?¶
Scenario: 10,000 VMs, each sending updates
Problem: API server is overloaded
Solutions:
1. Increase interval:
Load calculation: - 10,000 VMs × 2KB / 30s = ~667 KB/s - 10,000 VMs × 2KB / 300s = ~67 KB/s (10× less!)
2. Add jitter (requires code change):
3. Load balancing: - Multiple API servers - Client distributed across different servers
Q: Can I batch updates?¶
Problem: Want to send multiple updates in one request
Answer: Currently not supported. Each update is a separate POST request (main.go:80).
Possible extension: - Collect updates in queue - Send all every X seconds or at Y updates - Requires API server change
Security¶
Q: HTTPS connection fails¶
Problem:
Cause: - Self-signed certificate - CA not trusted
Solution:
Option 1: Install CA certificate
# Copy certificate
sudo cp ca-cert.pem /usr/local/share/ca-certificates/
# Update CA trust
sudo update-ca-certificates
Option 2: Skip certificate verification (NOT for production!) Requires code change (main.go:66-68)
Best practice: Use valid TLS certificates (Let's Encrypt)
Q: API authentication missing¶
Problem: Anyone can send data to API
Current state: No authentication implemented (main.go:80)
Possible extensions:
- API key in header: Authorization: Bearer <token>
- mTLS (Mutual TLS)
- OAuth2
Workaround: - Firewall rules (only known IPs) - VPN/Private network - API gateway with authentication
Known Limitations¶
L1: Only IPv4 support¶
Problem: No IPv6 addresses are detected
Code: main.go:49
Workaround: Use interface with IPv4 address or extend code for IPv6.
L2: No reconnect on API server restart¶
Problem: Initial registration fails if API server is not running → Client exits
Code: main.go:160-162
if retryCount >= maxRetries {
log.Fatalf("Failed to register after %d attempts, exiting", maxRetries)
}
Workaround:
- Systemd with Restart=always
- Longer retry delay
- Start API server before client
L3: No configuration file support¶
Problem: All parameters via CLI flags
Workaround: - Systemd unit files - Wrapper scripts - Environment variables (requires code change)
L4: Hardcoded max. 3 retries¶
Problem: maxRetries := 3 is hardcoded (main.go:126)
Workaround: Currently none. Extension to CLI flag possible.
L5: No HTTP timeouts¶
Problem: Can wait forever for HTTP response
Code: main.go:67 uses http.Post() without timeout
Workaround: Currently none. Recommended extension: Custom HTTP client with timeout.
Helpful Commands (Cheat Sheet)¶
Diagnostic Commands¶
# Show network interfaces
ip addr show # Linux
ifconfig # macOS/BSD
netstat -i # All systems
# Test API reachability
curl -v http://api:8080/api/register
nc -zv api 8080
# View logs
journalctl -u vm-tracker-client -f # Systemd
docker logs -f vm-tracker-client # Docker
kubectl logs -f pod/vm-tracker-client # Kubernetes
# Process status
ps aux | grep vm-tracker-client
pgrep -f vm-tracker-client
systemctl status vm-tracker-client
# Resource usage
top -p $(pgrep vm-tracker-client)
docker stats vm-tracker-client
Test Commands¶
# Unit tests
go test -v
go test -v -cover
go test -bench=. -benchmem
# Manual testing
./vm-tracker-client -verbose -api "http://localhost:8080"
# Race detection
go run -race main.go
# Network capture
sudo tcpdump -i eth0 -A 'tcp port 8080'
Further Help¶
Where can I find more documentation?¶
- API Reference: api/reference
- Test Documentation: api/reference.md
- Source Code: main.go, main_test.go
Problem not solved?¶
- Activate verbose logging:
-verbose - Check logs:
journalctl -u vm-tracker-client -n 100 - Run tests:
go test -v - Create issue: In the repository
Contributing¶
Have additional FAQ entries? PRs are welcome!
Version: 1.0 Last Updated: 2025-11-04 Maintainer: VM Tracker Team