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

  1. Regenerate a proper base64 key with `openssl rand -base64 32` and set it exactly as printed.
  2. Strip quotes and whitespace from the configured value (env vars often pick up surrounding quotes from .env files).
  3. If the key was generated as hex (`openssl rand -hex 32`), re-encode: `openssl rand -hex 32 | xxd -r -p | base64`.
  4. 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

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


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)