gotify/server · warning

client not found

Error message

client not found

What it means

This is an HTTP 404 raised in the client privilege-elevation handler when GetClientByID returns no client for the path ID, or when the client exists but belongs to a different user than the authenticated one. The library deliberately collapses 'missing' and 'not yours' into a single 404 to avoid leaking resource existence to other users. It is not a database failure — 500 is used separately for DB errors.

Source

Thrown at api/client.go:314

//	        $ref: "#/definitions/Error"
//	  404:
//	    description: Not Found
//	    schema:
//	        $ref: "#/definitions/Error"
func (a *ClientAPI) ElevateClient(ctx *gin.Context) {
	withID(ctx, "id", func(id uint) {
		var params model.ElevateRequest
		if err := ctx.Bind(&params); err != nil {
			return
		}

		client, err := a.DB.GetClientByID(id)
		if err != nil {
			ctx.AbortWithError(500, err)
			return
		}
		if client == nil || client.UserID != auth.GetUserID(ctx) {
			ctx.AbortWithError(404, errors.New("client not found"))
			return
		}

		elevatedUntil := time.Now().Add(time.Duration(params.DurationSeconds) * time.Second)
		if err := a.DB.UpdateClientElevatedUntil(client.ID, &elevatedUntil); err != nil {
			ctx.AbortWithError(500, err)
			return
		}

		ctx.Status(204)
	})
}

View on GitHub (pinned to 14bfc25627)

Solutions

  1. List your clients (GET /client) with the same token and confirm the ID exists in that response before elevating it.
  2. Verify you are authenticating as the user who owns the client — a valid ID from another user also returns 404.
  3. Check for typos or truncated IDs in the URL path; the ID must be the numeric client ID, not a token or name.
  4. If the client was deleted, create a new client and use its ID.

Example fix

// before
curl -X POST https://gotify.example/client/999/elevate -H 'X-Gotify-Key: WRONG_USER_TOKEN'

// after
# fetch clients with the owning user's token, then use a returned id
curl -H 'X-Gotify-Key: <user-token>' https://gotify.example/client
# -> [{"id": 42, ...}]
curl -X POST -H 'X-Gotify-Key: <user-token>' https://gotify.example/client/42/elevate
Defensive patterns

Strategy: validation

Validate before calling

// Client-side pre-check before calling the elevate endpoint
const clients = await fetch('/client', { headers: { 'X-Gotify-Key': token } }).then(r => r.json());
const mine = clients.find(c => c.id === clientId);
if (!mine) throw new Error(`client ${clientId} not found for this user — refusing to call elevate`);

Try / catch

// The error surfaces as HTTP 404, not an exception
const res = await fetch(`/client/${clientId}/elevate`, { method: 'POST', headers: { 'X-Gotify-Key': token } });
if (res.status === 404) {
  // missing OR not owned — refresh client list and re-check ownership
  console.warn('client not found: verify ID and that it belongs to your user');
}

Prevention

When it happens

Trigger: Calling the client elevation endpoint (e.g. POST /client/{id}/elevate) with: (1) a client ID that does not exist, (2) a client ID that was deleted, or (3) a client ID owned by another authenticated user (client.UserID != auth.GetUserID).

Common situations: Stale IDs cached in scripts or mobile apps after the client was revoked; copy-pasting a client ID from another account/environment; testing with an admin token but a client from a normal user account; ID confusion between application IDs and client IDs.

Related errors


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