gotify/server · error

you are not allowed to create an admin user

Error message

you are not allowed to create an admin user

What it means

Returned by CreateUser when a caller without global admin rights attempts to create a user with the admin flag set. Even when self-registration (a.Registration) is enabled, registration may only ever create non-admin accounts; internal.Admin triggers a 401/403 abort matching the requester's auth status.

Source

Thrown at api/user.go:230

		if uid != nil {
			requestedBy, err = a.DB.GetUserByID(*uid)
			if err != nil {
				ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("could not get user: %s", err))
				return
			}
		}

		if requestedBy == nil || !requestedBy.Admin {
			status := http.StatusUnauthorized
			if requestedBy != nil {
				status = http.StatusForbidden
			}
			if !a.Registration {
				ctx.AbortWithError(status, errors.New("you are not allowed to access this api"))
				return
			}
			if internal.Admin {
				ctx.AbortWithError(status, errors.New("you are not allowed to create an admin user"))
				return
			}
		}

		if existingUser == nil {
			if success := successOrAbort(ctx, 500, a.DB.CreateUser(internal)); !success {
				return
			}
			if err := a.UserChangeNotifier.fireUserAdded(internal.ID); err != nil {
				ctx.AbortWithError(500, err)
				return
			}
			ctx.JSON(200, toExternalUser(internal))
		} else {
			ctx.AbortWithError(400, errors.New("username already exists"))
		}
	}
}

View on GitHub (pinned to 14bfc25627)

Solutions

  1. Use an admin account to create admin users
  2. Remove "admin": true from the request body for self-registration flows
  3. Create the first admin via the server's CLI/bootstrap mechanism, not the public API
  4. Create a normal user first, then elevate with an admin UpdateUser call

Example fix

// before
curl -X POST https://host/api/users -d '{"username":"bob","admin":true}'
// after
curl -X POST https://host/api/users -u 'admin:s3cret' -d '{"username":"bob","admin":true}'
Defensive patterns

Strategy: validation

Validate before calling

if (payload.admin === true && !isAdminAccount(currentUser)) {
  throw new Error('only admins may create admin users; drop the admin flag or use admin credentials');
}

Type guard

function isAdminCreationRequest(payload, requester) {
  return payload.admin === true && !(requester && requester.admin === true);
}

Try / catch

try {
  await api.createUser(payload);
} catch (e) {
  if (e.status === 403 && /admin user/.test(e.message)) { retry as non-admin or with admin creds }
  else { throw e; }
}

Prevention

When it happens

Trigger: POST /api/users with {"admin": true} in the body while authenticated as a non-admin (or anonymously with registration on); automation that copies an admin user object as a template and re-submits it; scripts attempting privilege escalation through the register endpoint.

Common situations: Onboarding tooling that always sends admin:true; API clients written when registration accepted any payload now blocked after a security fix; attempts to bootstrap a first admin through the public API instead of a CLI/init step.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05). Data as JSON: /api/errors/aac2de6eebc483a3. Report an issue: GitHub.