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

  1. Set the access key's Type to ssh if the stored value really is a plaintext private key.
  2. Strip the trailing newline and re-store the secret so it is treated as encrypted data (or re-encrypt it properly).
  3. 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

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


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)