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(¶ms); 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
- List your clients (GET /client) with the same token and confirm the ID exists in that response before elevating it.
- Verify you are authenticating as the user who owns the client — a valid ID from another user also returns 404.
- Check for typos or truncated IDs in the URL path; the ID must be the numeric client ID, not a token or name.
- 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
- Always fetch IDs from GET /client with the same token you will elevate with.
- Remember 404 also means 'not owned by you' — never retry blindly with another user's token.
- Clear cached client IDs after revoking or recreating clients.
- Distinguish client IDs from application IDs; they are separate ID spaces.
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
- application does not exist
- application does not exists
- message does not exist
- unknown plugin
- cannot delete internal application
AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05).
Data as JSON: /api/errors/a89bf23662da1336.
Report an issue: GitHub.