semaphoreui/semaphore · error
unsupported source storage type
Error message
unsupported source storage type
What it means
Semaphore's secret-storage Update service normalizes the storage type of an existing access-key secret before rewriting it. The caller passes a pointer to the secret's current source storage type; only env-var and file sources can be migrated in place, so any other value (e.g. vault-sourced) hits the default branch and Update aborts with this error before creating the new key.
Solutions
- Check the secret's source storage type before calling Update and skip/branch when it is vault-sourced (AccessKeySourceStorageVault)
- Remove or correct the invalid source_storage_type value in the database so it is one of env/file
- Pass a nil sourceStorageType if you do not intend to migrate the storage source
- Update Semaphore to a version that supports the storage type in question
Example fix
// before
err = secretStorage.Update(ctx, projectID, secretID, &vaultStorageType)
// after
if vaultStorageType == db.AccessKeySourceStorageVault {
return nil // vault-sourced secrets are managed by vault, nothing to migrate
}
err = secretStorage.Update(ctx, projectID, secretID, &vaultStorageType) Defensive patterns
Strategy: validation
Validate before calling
func canMigrate(s *db.AccessKeySourceStorageType) bool {
return s != nil && (*s == db.AccessKeySourceStorageEnv || *s == db.AccessKeySourceStorageFile)
}
// if !canMigrate(&storageType) { skip Update } Type guard
if sourceStorageType == nil || (*sourceStorageType != db.AccessKeySourceStorageEnv && *sourceStorageType != db.AccessKeySourceStorageFile) { /* skip or branch */ } Prevention
- Check source storage type before invoking Update for secret migration
- Never hand-edit source_storage_type values in the database
- Keep server and vault integration versions in sync
When it happens
Trigger: Calling Update on a secret whose sourceStorageType pointer is non-nil but not db.AccessKeySourceStorageEnv or db.AccessKeySourceStorageFile — typically when the secret was created directly in the vault (AccessKeySourceStorageVault) or carries a stale/unknown storage-type string from the database.
Common situations: Migrating secrets that were created through the vault-integration path instead of the classic env/file path; a data migration or manual DB edit left an unexpected value in source_storage_type; a client API call sends an explicit storage type the service does not support.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- missing secret
- secret must be valid json in key
- invalid ssh key
- invalid password key
- secret does not belong to this environment
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/1a86b5dd894d79e9.
Report an issue: GitHub.
Appendix: source
Thrown at services/server/secret_storage_svc.go:188
return
}
if len(keys) == 0 {
if storage.Secret == "" {
// empty vault token means the user didn't set a new token,
// so we don't create a new access key.
return
}
sourceStorageType := storage.SourceStorageType
sourceStorageKey := ""
if sourceStorageType != nil {
switch *sourceStorageType {
case db.AccessKeySourceStorageEnv, db.AccessKeySourceStorageFile:
sourceStorageKey = storage.Secret
default:
err = errors.New("unsupported source storage type")
return
}
}
newKey := db.AccessKey{
Name: random.String(10),
Type: db.AccessKeyString,
ProjectID: &storage.ProjectID,
Owner: db.AccessKeySecretStorage,
StorageID: &storage.ID,
SourceStorageType: sourceStorageType,
}
if sourceStorageKey != "" {
newKey.SourceStorageKey = &sourceStorageKey
} else {
newKey.String = storage.Secret
}View on GitHub (pinned to 1774ccb71a)