gotify/server · warning

application does not exist

Error message

application does not exist

What it means

An HTTP 404 raised by the GET messages endpoint when the requested application ID either does not exist or exists but belongs to a different user. The handler first resolves the application; if the application is nil or its UserID does not match the authenticated user, it aborts with 'application does not exist' instead of listing messages. Note error 8 uses the near-identical but typo'd message 'application does not exists' on the DELETE path — both mean the same thing.

Source

Thrown at api/message.go:191

//	    description: Not Found
//	    schema:
//	        $ref: "#/definitions/Error"
func (a *MessageAPI) GetMessagesWithApplication(ctx *gin.Context) {
	withID(ctx, "id", func(id uint) {
		withPaging(ctx, func(params *pagingParams) {
			app, err := a.DB.GetApplicationByID(id)
			if success := successOrAbort(ctx, 500, err); !success {
				return
			}
			if app != nil && app.UserID == auth.GetUserID(ctx) {
				// the +1 is used to check if there are more messages and will be removed on buildWithPaging
				messages, err := a.DB.GetMessagesByApplicationSince(id, params.Limit+1, params.Since)
				if success := successOrAbort(ctx, 500, err); !success {
					return
				}
				ctx.JSON(200, buildWithPaging(ctx, params, messages))
			} else {
				ctx.AbortWithError(404, errors.New("application does not exist"))
			}
		})
	})
}

// DeleteMessages delete all messages from a user.
// swagger:operation DELETE /message message deleteMessages
//
// Delete all messages.
//
//	---
//	produces: [application/json]
//	security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
//	responses:
//	  200:
//	    description: Ok
//	  401:
//	    description: Unauthorized

View on GitHub (pinned to 14bfc25627)

Solutions

  1. Call GET /application with your token and confirm the application ID appears in the list before querying its messages.
  2. Ensure the token used for the message query belongs to the same user who owns the application.
  3. If the application was deleted, recreate it and use the new application ID.
  4. Verify the request targets the correct server/instance (IDs are not globally unique across installations).

Example fix

// before
curl 'https://gotify.example/message?token=<tok>&app_id=999'   # app 999 not owned -> 404

// after
# 1. confirm ownership
apps=$(curl -s -H 'X-Gotify-Key: <user-token>' https://gotify.example/application)
# 2. use a returned application id
curl -s -H 'X-Gotify-Key: <user-token>' 'https://gotify.example/message?token=<app-token>&since=0&limit=100'
Defensive patterns

Strategy: validation

Validate before calling

// Verify the application exists and is yours before polling its messages
const apps = await fetch('/application', { headers: { 'X-Gotify-Key': userToken } }).then(r => r.json());
if (!apps.some(a => a.id === appId)) {
  throw new Error(`application ${appId} does not exist for this user`);
}
// safe to proceed: fetch(`/message?token=${appToken}&since=${since}&limit=${limit}`)

Try / catch

const res = await fetch(`/message?token=${tok}&since=${since}`, { headers: { 'X-Gotify-Key': userToken } });
if (res.status === 404) {
  // re-list applications; if absent, resubscribe to a valid app instead of retrying the same ID
  console.warn('application missing or not owned — refresh application list');
}

Prevention

When it happens

Trigger: GET /message?since=...&limit=... (the message listing endpoint) with an application ID that (1) does not exist, (2) was deleted, or (3) is owned by another user.

Common situations: Querying messages shortly after deleting the application; using an application ID from a different Gotify instance or environment; another user's application ID (404 is intentional to avoid leaking existence); token belongs to a different user than the application owner.

Related errors


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