t8y2/dbx · error
auth: User %s already exists.
Error message
auth: User %s already exists.
What it means
The etcd2 agent's authUserAdd performs an HTTP PUT to /v2/auth/users/<user> to create a user; the etcd v2 auth API returns 200 for an existing user, so the agent interprets a 200 as 'the user already exists' and surfaces this error instead of reporting success. Creating a duplicate user is rejected to avoid silently overwriting credentials.
Source
Thrown at agents/drivers/etcd2-go/auth.go:124
return nil, err
}
user, err := requiredString(params, "user")
if err != nil {
return nil, err
}
password, err := requiredString(params, "password")
if err != nil {
return nil, err
}
ctx, cancel := s.beginOperation()
defer s.endOperation(cancel)
payload := v2UserDocument{User: user, Password: password}
_, response, err := client.doJSON(ctx, http.MethodPut, "/v2/auth/users/"+escapePathSegment(user), payload)
if err != nil {
return nil, err
}
if response != nil && response.StatusCode == http.StatusOK {
return nil, fmt.Errorf("auth: User %s already exists.", user)
}
return map[string]bool{"created": true}, nil
}
func (s *etcd2Session) authUserDelete(params map[string]json.RawMessage) (any, error) {
client, err := s.activeClient()
if err != nil {
return nil, err
}
user, err := requiredString(params, "user")
if err != nil {
return nil, err
}
ctx, cancel := s.beginOperation()
defer s.endOperation(cancel)
if _, _, err := client.do(ctx, http.MethodDelete, "/v2/auth/users/"+escapePathSegment(user), "", nil); err != nil {
return nil, err
}View on GitHub (pinned to c0390bff16)
Solutions
- Check existence first (list auth users or attempt get) and skip creation if present
- Treat this error as idempotent success if the desired password is already set, or delete and re-add the user
- Use a new unique username if a separate account is truly needed
Example fix
// before
agent.call("auth user add", map[string]any{"user": "alice", "password": pw})
// after
users, _ := agent.call("auth user list", nil)
if !contains(users, "alice") {
agent.call("auth user add", map[string]any{"user": "alice", "password": pw})
} Defensive patterns
Strategy: try-catch
Validate before calling
// check the user list before adding
users, err := agent.Call("auth user list", nil)
if err == nil && containsUser(users, "alice") {
return nil // already provisioned
} Type guard
func isUserExists(err error) bool {
return err != nil && strings.Contains(err.Error(), "already exists")
} Try / catch
_, err := agent.Call("auth user add", map[string]any{"user": u, "password": pw})
if isUserExists(err) {
return nil // treat as idempotent success or update password instead
} Prevention
- Make provisioning scripts idempotent: check-then-create
- Run a single provisioner to avoid concurrent duplicate creation
- On redeploys, reuse existing users instead of re-adding
When it happens
Trigger: Calling auth user add (authUserAdd) for a user name that already exists in the etcd auth user list.
Common situations: Re-running provisioning scripts that create users idempotently without checking existence; a previous partially-failed setup already created the user; two operators creating the same username concurrently.
Related errors
- Agent session already exists: %s
- ETCD_INVALID_ACCESS
- user is required
- ETCD_WATCH_SCOPE_INVALID
- ETCD_WATCH_NOT_FOUND
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/79eb0bbe899cfd05.
Report an issue: GitHub.