JuliusBrussee/caveman · warning

password must be at least %d bytes

Error message

password must be at least %d bytes

What it means

security.ValidatePassword enforces a minimum input length of MinPasswordBytes = 12 bytes (bytes, not runes) before the value is used for key derivation (argon2). Short passwords are rejected because argon2 cannot extract enough entropy from them regardless of cost parameters.

Source

Thrown at shared/platform/security/keys.go:22

	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"strings"

	"golang.org/x/crypto/argon2"
)

const (
	MinPasswordBytes = 12
	MaxPasswordBytes = 1024
)

func ValidatePassword(password string) error {
	if len(password) < MinPasswordBytes {
		return fmt.Errorf("password must be at least %d bytes", MinPasswordBytes)
	}
	if len(password) > MaxPasswordBytes {
		return fmt.Errorf("password must be at most %d bytes", MaxPasswordBytes)
	}
	return nil
}

func GenerateProjectKey() (string, string, error) {
	raw := make([]byte, 32)
	if _, err := rand.Read(raw); err != nil {
		return "", "", err
	}
	secret := base64.RawURLEncoding.EncodeToString(raw)
	full := "cave_live_" + secret[:12] + "_" + secret[12:]
	return full, secret[:12], nil
}

func HashProjectKey(pepper, full string) string {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Enforce a >=12-byte minimum in the UI/CLI before submitting (note bytes vs characters for multibyte input).
  2. Update test fixtures and seed data to use passwords of at least 12 bytes.
  3. If you genuinely need shorter values, generate a random passphrase rather than weakening the constant.

Example fix

// before
pw := r.FormValue("password")
hash, err := security.DeriveKey(pw) // fails inside validation

// after
pw := r.FormValue("password")
if err := security.ValidatePassword(pw); err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
}
Defensive patterns

Strategy: validation

Validate before calling

if len(password) < security.MinPasswordBytes {
    return fmt.Errorf("password too short (min %d bytes)", security.MinPasswordBytes)
}

Type guard

func hasMinPasswordBytes(pw string) bool { return len(pw) >= security.MinPasswordBytes }

Try / catch

if err := security.ValidatePassword(pw); err != nil {
    // 400 to the client with err.Error(); input problem, not a server fault
}

Prevention

When it happens

Trigger: Calling security.ValidatePassword with a string shorter than 12 bytes, e.g. a 8-character ASCII password or a multi-byte string whose UTF-8 encoding is under 12 bytes.

Common situations: User signup/login forms without a client-side minimum; test fixtures using 'pass' or '1234'; CJK input where fewer characters than expected still measure 12+ bytes or vice versa.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/328c8043736894e7. Report an issue: GitHub.