kopia/kopia · warning
ErrUserAlreadyExists
ErrUserAlreadyExists
Error message
user already exists
What it means
ErrUserAlreadyExists is the sentinel returned when attempting to create a new user profile whose username@hostname label already has manifests in the repository, enforcing uniqueness of server users (internal/user/user_manager.go:117).
Solutions
- Check existence first (GetUserProfile) and update the existing profile instead of creating a new one.
- Match with errors.Is(err, user.ErrUserAlreadyExists) and treat as success in idempotent setup scripts.
- Use a different username@hostname if a genuinely separate account is intended.
Example fix
// before
p, err := user.SetupUser(ctx, rep, "alice@somehost", pwd) // fails on re-run
// after
if _, err := user.GetUserProfile(ctx, rep, "alice@somehost"); errors.Is(err, user.ErrUserNotFound) {
_, err = user.SetupUser(ctx, rep, "alice@somehost", pwd)
}
// else: user already exists, reuse it Defensive patterns
Strategy: try-catch
Validate before calling
// before creating, check for existing user _, err := user.GetUserProfile(ctx, rep, "alice@somehost") exists := !errors.Is(err, user.ErrUserNotFound)
Try / catch
p, err := user.SetupUser(ctx, rep, "alice@somehost", pwd)
if errors.Is(err, user.ErrUserAlreadyExists) {
// idempotent: fetch and reuse the existing profile
p, err = user.GetUserProfile(ctx, rep, "alice@somehost")
} Prevention
- Make user provisioning idempotent: check then create, or treat already-exists as success.
- Always match with errors.Is(err, user.ErrUserAlreadyExists).
- Avoid re-running 'kopia server user add' for existing users; update instead.
- Ensure only one server instance manages a given repository's users.
When it happens
Trigger: Calling user.GetNewProfile(ctx, rep, username) (or SetupUser) when the repository already contains one or more user manifests labeled with that username (len(manifests) != 0).
Common situations: Re-running 'kopia server user add' for an existing user; provisioning scripts that are not idempotent and re-create users on each run; two server instances sharing one repository both registering the same user.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- ErrUserNotFound
- error connecting to repository
- error opening repository
- repository is not writable
- unable to initialize repository
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/d42242e20e8602fc.
Report an issue: GitHub.
Appendix: source
Thrown at internal/user/user_manager.go:27
"strings"
"github.com/pkg/errors"
"github.com/kopia/kopia/repo"
"github.com/kopia/kopia/repo/manifest"
)
// ManifestType is the type of the manifest used to represent user accounts.
const ManifestType = "user"
// UsernameAtHostnameLabel is the manifest label identifying users by username@hostname.
const UsernameAtHostnameLabel = "username"
// ErrUserNotFound is returned to indicate that a user was not found in the system.
var ErrUserNotFound = errors.New("user not found")
// ErrUserAlreadyExists indicates that a user already exist in the system when attempting to create a new one.
var ErrUserAlreadyExists = errors.New("user already exists")
// LoadProfileMap returns the map of all users profiles in the repository by username, using old map as a cache.
func LoadProfileMap(ctx context.Context, rep repo.Repository, old map[string]*Profile) (map[string]*Profile, error) {
if rep == nil {
return nil, nil
}
entries, err := rep.FindManifests(ctx, map[string]string{manifest.TypeLabelKey: ManifestType})
if err != nil {
return nil, errors.Wrap(err, "error listing user manifests")
}
result := map[string]*Profile{}
for _, m := range manifest.DedupeEntryMetadataByLabel(entries, UsernameAtHostnameLabel) {
user := m.Labels[UsernameAtHostnameLabel]
// same user info as beforeView on GitHub (pinned to 82495e54b5)