glanceapp/glance · critical
decoding secret-key: %v
Error message
decoding secret-key: %v
What it means
Thrown during application startup when auth is configured (users exist) and the `auth.secret-key` value cannot be base64-decoded with standard encoding. The secret key is stored as base64 in the YAML config, so any character outside the standard base64 alphabet or wrong padding makes DecodeString fail.
Source
Thrown at internal/glance/glance.go:64
func newApplication(c *config) (*application, error) {
app := &application{
Version: buildVersion,
CreatedAt: time.Now(),
Config: *c,
slugToPage: make(map[string]*page),
widgetByID: make(map[uint64]widget),
}
config := &app.Config
//
// Init auth
//
if len(config.Auth.Users) > 0 {
secretBytes, err := base64.StdEncoding.DecodeString(config.Auth.SecretKey)
if err != nil {
return nil, fmt.Errorf("decoding secret-key: %v", err)
}
if len(secretBytes) != AUTH_SECRET_KEY_LENGTH {
return nil, fmt.Errorf("secret-key must be exactly %d bytes", AUTH_SECRET_KEY_LENGTH)
}
app.usernameHashToUsername = make(map[string]string)
app.failedAuthAttempts = make(map[string]*failedAuthAttempt)
app.RequiresAuth = true
for username := range config.Auth.Users {
user := config.Auth.Users[username]
usernameHash, err := computeUsernameHash(username, secretBytes)
if err != nil {
return nil, fmt.Errorf("computing username hash for user %s: %v", username, err)
}
app.usernameHashToUsername[string(usernameHash)] = username
View on GitHub (pinned to 91324e8de7)
Solutions
- Regenerate the key properly: `openssl rand -base64 64` and paste the single-line result into auth.secret-key
- Ensure no whitespace/newlines/url-safe substitutions are present; standard alphabet only (A-Z a-z 0-9 + / =)
- If the value comes from a template/env substitution, verify padding characters survive injection
Example fix
# before
auth:
secret-key: "hGk9...raw-64-bytes...==(" # not valid base64
# after (generate correctly)
# openssl rand -base64 64
auth:
secret-key: "K9dX...single-line-base64...=="
Defensive patterns
Strategy: validation
Validate before calling
// Validate secret-key before handing config to glance
import "encoding/base64"
func secretKeyValid(s string) error {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil { return fmt.Errorf("secret-key is not standard base64: %w", err) }
if len(b) != 64 { return fmt.Errorf("secret-key decodes to %d bytes, want 64", len(b)) }
return nil
}
Try / catch
Treat as fatal config error; catch at startup, print the regen command (`openssl rand -base64 64`), and exit — never fall back to a default key.
Prevention
- Always generate with `openssl rand -base64 64`
- Store the key in a secret manager and inject verbatim; avoid shell transformations
- Add a pre-deploy check that base64-decodes and length-checks the key
When it happens
Trigger: Setting `secret-key` to a raw 64-byte random string instead of its base64 encoding; hand-editing the key and introducing spaces, url-safe (-/_) characters, or truncating/wrapping the value; using base64url encoding instead of standard base64.
Common situations: Generating a key with `openssl rand 64` (raw bytes) instead of `openssl rand -base64 64`; copying a key with a line break from a terminal; secret injected via environment templating that mangles padding ('=' signs stripped).
Related errors
- secret-key must be exactly %d bytes
- hashing password for user %s: %v
- computing username hash for user %s: %v
- initializing preset theme %s: %v
- initializing default theme: %v
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/fadd24063c185de0.
Report an issue: GitHub.