ory/kratos · error

at most IDs may be provided per call

Error message

at most %d IDs may be provided per call

What it means

parseManageSessionsIDs enforces a hard upper bound of ManageSessionsMaxIDs session UUIDs per call; exceeding it returns this error. The limit exists to keep the request payload and the resulting session-lookup/invalidation work bounded.

Solutions

  1. Split the ID list into chunks of at most ManageSessionsMaxIDs and issue one API call per chunk.
  2. Fetch the cap from the exported ManageSessionsMaxIDs constant (or probe server behavior) and chunk dynamically instead of hard-coding a larger size.
  3. If the goal is to invalidate all sessions for a user/identity, use the wildcard ('*') variant of the endpoint rather than enumerating every ID.
  4. Batch client-side: accumulate session IDs and flush when the chunk size is reached.

Example fix

// before
await ory.disableSessions({ session_ids: allIds })  // allIds.length > ManageSessionsMaxIDs
// after
for (let i = 0; i < allIds.length; i += ManageSessionsMaxIDs) {
  await ory.disableSessions({ session_ids: allIds.slice(i, i + ManageSessionsMaxIDs) })
}
Defensive patterns

Strategy: validation

Validate before calling

const MAX = 30 /* ManageSessionsMaxIDs */
if (sessionIds.length > MAX) {
  throw new Error(`chunk required: max ${MAX} ids per call`)
}

Try / catch

if strings.Contains(err.Error(), "may be provided per call") {
    // split the list and retry in batches
}

Prevention

When it happens

Trigger: Calling the session management endpoint with more than ManageSessionsMaxIDs UUIDs in the IDs array (e.g. batch-disabling thousands of sessions in one request). Check ManageSessionsMaxIDs in session/handler.go for the exact cap.

Common situations: Admin tooling that tries to disable every user session in one bulk call; sync jobs exporting all stale sessions and posting them in a single request; scripts written before the batch limit was introduced.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07). Data as JSON: /api/errors/0ec13e5f20843756. Report an issue: GitHub.

Appendix: source

Thrown at session/handler.go:1394

// accept wildcard should call parseManageSessionsIDs directly so the token is
// rejected.
func parseManageSessionsIDsOrWildcard(raw []string) (ids []uuid.UUID, wildcard bool, err error) {
	if len(raw) == 1 && raw[0] == ManageSessionsAllToken {
		return nil, true, nil
	}
	ids, err = parseManageSessionsIDs(raw)
	return ids, false, err
}

// parseManageSessionsIDs interprets a manage-sessions filter array as a list
// of explicit UUIDs and rejects any input containing the wildcard token.
// Callers that accept the wildcard must use parseManageSessionsIDsOrWildcard.
func parseManageSessionsIDs(raw []string) ([]uuid.UUID, error) {
	if len(raw) == 0 {
		return nil, errors.New("array must not be empty")
	}
	if len(raw) > ManageSessionsMaxIDs {
		return nil, fmt.Errorf("at most %d IDs may be provided per call", ManageSessionsMaxIDs)
	}
	ids := make([]uuid.UUID, 0, len(raw))
	for _, s := range raw {
		if s == ManageSessionsAllToken {
			return nil, errors.New("the wildcard '*' is not accepted here")
		}
		id, err := uuid.FromString(s)
		if err != nil {
			return nil, fmt.Errorf("could not parse %q as UUID: %w", s, err)
		}
		ids = append(ids, id)
	}
	return ids, nil
}

// wildcardBatch runs a single chunked bulk-session operation and packages the
// row count plus a `more` flag for the response. `more` is true when the call
// reached the per-call batch limit, signaling that the caller should re-issue

View on GitHub (pinned to b86338da04)