glanceapp/glance · critical
decoding secret-key
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.
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
- hashing password for user
- secret-key must be exactly
- computing username hash for user
- creating application
- initializing default theme
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/fadd24063c185de0.
Report an issue: GitHub.
Appendix: 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)