semaphoreui/semaphore · error
invalid access key type
Error message
invalid access key type
What it means
As a backward-compatibility path, deserialize treats a stored secret ending in '\n' as an unencrypted (plaintext) SSH private key from old Semaphore versions. If such a legacy plaintext value is found but the key's Type is not AccessKeySSH, the data is inconsistent and the error 'invalid access key type' is returned.
Solutions
- Set the access key's Type to ssh if the stored value really is a plaintext private key.
- Strip the trailing newline and re-store the secret so it is treated as encrypted data (or re-encrypt it properly).
- Re-create the key through the API so the serializer encrypts and types it correctly.
Example fix
// before: login_password key storing "pass\n" (looks like legacy plaintext) secret = strings.TrimRight(secret, "\n"); re-encrypt via SerializeSecret // after: properly encrypted secret with matching key type
Defensive patterns
Strategy: validation
Validate before calling
if strings.HasSuffix(*key.Secret, "\n") && key.Type != db.AccessKeySSH {
// legacy plaintext path will reject this: trim/re-encrypt or fix the type
} Try / catch
if _, err := svc.DeserializeSecret(key); err != nil && strings.Contains(err.Error(), "invalid access key type") { /* re-type or re-encrypt the key */ } Prevention
- Trim trailing newlines when importing legacy key material.
- Store plaintext legacy private keys only under ssh-type keys.
- Migrate legacy plaintext keys to encrypted storage promptly.
When it happens
Trigger: DeserializeSecret/DeserializeSecret2 on an AccessKey whose stored Secret ends with a newline (detected as legacy plaintext private key) but whose Type is not ssh — e.g. a login/password key whose stored value accidentally ends in '\n'.
Common situations: Legacy data imported from pre-encryption Semaphore; secrets pasted with trailing newlines into non-SSH keys; import scripts not trimming/normalizing key material.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- invalid ssh key
- missing secret
- secret must be valid json in key
- invalid password key
- source storage key is required
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/b3c3d8e38f1ae282.
Report an issue: GitHub.
Appendix: source
Thrown at services/server/access_key_serializer_local.go:157
var data []byte
data, err = os.ReadFile(filePath)
if err != nil {
return
}
res = strings.TrimSuffix(string(data), "\n")
return
}
}
if key.Secret == nil || *key.Secret == "" {
return
}
secret := *key.Secret
if secret[len(secret)-1] == '\n' { // not encrypted private key, used for back compatibility
if key.Type != db.AccessKeySSH {
err = fmt.Errorf("invalid access key type")
return
}
sshKey := db.SshKey{
PrivateKey: secret,
}
var marshaled []byte
marshaled, err = json.Marshal(sshKey)
if err != nil {
return
}
res = string(marshaled)
return
}
View on GitHub (pinned to 1774ccb71a)