semaphoreui/semaphore · critical
cannot decrypt access key, perhaps encryption key was…
Error message
cannot decrypt access key, perhaps encryption key was changed
What it means
The stored secret ciphertext fails GCM/Authenticated-cipher verification ('cipher: message authentication failed'), which almost always means it was encrypted with a different encryption key than the one now configured. deserialize maps that specific cipher error to this human-readable message so operators know to check the encryption key (APSE encryption key / keyset).
Solutions
- Restore the original encryption key / keyset used when the secret was stored and retry.
- If the old key is still available, configure it temporarily and run RekeyAccessKeys to re-encrypt all secrets with the current key.
- If the key is lost, re-create the affected access keys with new secrets — the old ciphertext is unrecoverable.
Example fix
// before: new key configured, old ciphertext undecryptable util.Config.EncryptionKey = newKeySet // after: rekey with old key present, then switch util.Config.EncryptionKey = oldKeySet err := encryptionService.RekeyAccessKeys() // re-encrypts with current key
Defensive patterns
Strategy: try-catch
Try / catch
if _, err := svc.DeserializeSecret(key); err != nil && strings.Contains(err.Error(), "cannot decrypt access key") { // encryption key changed
// restore original key, or run RekeyAccessKeys with the old key configured
} Prevention
- Back up the encryption keyset securely alongside DB backups.
- Never rotate the encryption key without running RekeyAccessKeys afterwards.
- Keep one authoritative encryption key per environment; don't copy DBs across environments with different keys.
When it happens
Trigger: DeserializeSecret/DeserializeSecret2 decrypt() returns the GCM message-authentication-failure error — the server's configured encryption key differs from the key used when the secret was stored (key rotated/replaced, wrong APSE key id, restored DB without the matching key).
Common situations: Rotating or regenerating the server encryption key without rekeying access keys (RekeyAccessKeys not run); moving the DB between environments with different encryption keys; restoring a backup while the keyset file changed.
Related errors
- missing secret
- secret must be valid json in key
- invalid ssh key
- invalid password key
- source storage key is required
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/fecbffbedb2bf041.
Report an issue: GitHub.
Appendix: source
Thrown at services/server/access_key_serializer_local.go:179
sshKey := db.SshKey{
PrivateKey: secret,
}
var marshaled []byte
marshaled, err = json.Marshal(sshKey)
if err != nil {
return
}
res = string(marshaled)
return
}
plaintext, decErr := decrypt(secret)
if decErr != nil {
if decErr.Error() == "cipher: message authentication failed" {
err = fmt.Errorf("cannot decrypt access key, perhaps encryption key was changed")
} else {
err = decErr
}
return
}
res = string(plaintext)
return
}
View on GitHub (pinned to 1774ccb71a)