glanceapp/glance · warning

usernames must be at least 3 characters

Error message

usernames must be at least 3 characters

What it means

Glance collects system info for the System widget and wraps every failure from gopsutil's mem.SwapMemory() as a collected warning. The error text is prefixed with 'getting swap memory info' and the raw gopsutil error follows. On non-fatal failures SwapIsAvailable stays false and the widget renders without swap stats.

Source

Thrown at internal/glance/config.go:466

// one of them, which doesn't modify the data and only checks for logical errors
// and then again when creating the application which does modify the data and do
// further validation. Would be better if validation was done in a single place.
func isConfigStateValid(config *config) error {
	if len(config.Pages) == 0 {
		return fmt.Errorf("no pages configured")
	}

	if len(config.Auth.Users) > 0 && config.Auth.SecretKey == "" {
		return fmt.Errorf("secret-key must be set when users are configured")
	}

	for username := range config.Auth.Users {
		if username == "" {
			return fmt.Errorf("user has no name")
		}

		if len(username) < 3 {
			return errors.New("usernames must be at least 3 characters")
		}

		user := config.Auth.Users[username]

		if user.Password == "" {
			if user.PasswordHashString == "" {
				return fmt.Errorf("user %s must have a password or a password-hash set", username)
			}
		} else if len(user.Password) < 6 {
			return fmt.Errorf("the password for %s must be at least 6 characters", username)
		}
	}

	if config.Server.AssetsPath != "" {
		if _, err := os.Stat(config.Server.AssetsPath); os.IsNotExist(err) {
			return fmt.Errorf("assets directory does not exist: %s", config.Server.AssetsPath)
		}
	}

View on GitHub (pinned to 91324e8de7)

Solutions

  1. If running in Docker/Podman, ensure /proc is mounted read-only into the container (it is by default; check for -v overrides or maskedPaths)
  2. On the host, verify with: cat /proc/swaps — if that fails, fix procfs mounting/permissions
  3. If the environment genuinely has no readable swap source, accept the degraded output: hide swap fields in the widget config so the warning is not surfaced
  4. Check the widget's error stream (errs slice) in logs to confirm the underlying gopsutil cause

Example fix

// before (docker-compose with restricted proc)
services:
  glance:
    volumes:
      - /proc:/proc:ro
// after: remove any proc masking so gopsutil can read /proc/swaps
services:
  glance:
    volumes:
      - /proc:/proc:ro   # default mount, do not override with :ro on a masked /proc
Defensive patterns

Strategy: try-catch

Validate before calling

v, err := mem.SwapMemory()
if err != nil {
    // swap unavailable; degrade gracefully
    log.Printf("swap info unavailable: %v", err)
}

Try / catch

Go idiom: check the returned error immediately and treat swap as optional. Glance already does this — SwapIsAvailable stays false and the error joins the collected errs slice, so callers render conditionally on info.Memory.SwapIsAvailable.

Prevention

When it happens

Trigger: mem.SwapMemory() is called during sysinfo collection (System widget with swap fields enabled). It fails when the platform's swap source is unreadable: /proc/swaps missing or unreadable on Linux, WMI/swap query failing on Windows, or unsupported behavior in minimal containers.

Common situations: Running the Glance container image with /proc not mounted or masked by systemd (PrivateMounts), a hardened/seccomp environment blocking the sysinfo call, or exotic BSD setups. On normal hosts swap data almost always resolves.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/58f86b59be13cb69. Report an issue: GitHub.