semaphoreui/semaphore · critical
access_key_encryption must be a valid base64 string
Error message
access_key_encryption must be a valid base64 string: %w
What it means
validateAccessKeyEncryption checks the access_key_encryption (or option_encryption) config value: it must be base64 that decodes into an AES key. This error is returned when base64.StdEncoding.DecodeString fails, meaning the configured value contains characters outside the base64 alphabet, wrong padding, or whitespace/quotes. It is surfaced as a startup panic via validateConfig.
Solutions
- Regenerate a proper base64 key with `openssl rand -base64 32` and set it exactly as printed.
- Strip quotes and whitespace from the configured value (env vars often pick up surrounding quotes from .env files).
- If the key was generated as hex (`openssl rand -hex 32`), re-encode: `openssl rand -hex 32 | xxd -r -p | base64`.
- Confirm base64 validity first: `echo "$ACCESS_KEY_ENCRYPTION" | base64 -d > /dev/null && echo ok`.
Example fix
// before export SEMAPHORE_ACCESS_KEY_ENCRYPTION="my secret passphrase" // after export SEMAPHORE_ACCESS_KEY_ENCRYPTION=$(openssl rand -base64 32)
Defensive patterns
Strategy: validation
Validate before calling
// Validate before deploying
value := os.Getenv("SEMAPHORE_ACCESS_KEY_ENCRYPTION")
if value != "" {
if _, err := base64.StdEncoding.DecodeString(value); err != nil {
log.Fatalf("access_key_encryption is not valid base64: %v", err)
}
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("invalid access_key_encryption: %v", r)
}
}() Prevention
- Always generate with `openssl rand -base64 32`.
- Strip quotes when storing values in .env files or Helm values.
- Add `echo -n "$VAL" | base64 -d >/dev/null` to pre-deploy smoke checks.
When it happens
Trigger: Config.AccessKeyEncryption or Config.OptionEncryption is non-empty and fails base64.StdEncoding.DecodeString in validateAccessKeyEncryption().
Common situations: Pasting a raw passphrase instead of a base64 key; shell added quotes when exporting the env var (SEMAPHORE_ACCESS_KEY_ENCRYPTION); value copied with trailing newline handled incorrectly (leading/trailing whitespace is actually accepted by StdEncoding? no — inner whitespace breaks it); generating a hex key instead of base64.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- access_key_encryption has invalid decoded length
- encryption_keys.keys_folder: key
- value of field ' ' is not valid: (Must match regex: ' ')
- : 'value' and 'file' are mutually exclusive
- OIDC sign-in failed: invalid state. Try signing in again.
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/6c543583510f1d42.
Report an issue: GitHub.
Appendix: source
Thrown at util/config.go:1735
return nil, err
}
var enc EncryptionKeysConfig
if err := json.Unmarshal(data, &enc); err != nil {
return nil, err
}
return &enc, nil
}
func validateAccessKeyEncryption(key string) error {
if key == "" {
return nil
}
encryption, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return fmt.Errorf("access_key_encryption must be a valid base64 string: %w", err)
}
switch len(encryption) {
case 16, 24, 32:
return nil
default:
return fmt.Errorf(
"access_key_encryption has invalid decoded length %d bytes; AES requires 16, 24, or 32 bytes (use `openssl rand -base64 32` to generate a valid key)",
len(encryption),
)
}
}
func validateConfig() {
err := validate(Config)
if err != nil {
panic(err)
}View on GitHub (pinned to 1774ccb71a)