keycloak/keycloak · error · Error

resourceId is not found in Location header from request: ${r

Error message

resourceId is not found in Location header from request: ${res.url}

What it means

Thrown by the admin-client agent after a `location` header was found, but splitting it on `/` and taking the last segment yields an empty string. This means the Location header is malformed for id extraction (e.g. it ends with a trailing slash or is a bare host), so the agent cannot derive a resource id and surfaces the unexpected shape.

Source

Thrown at js/libs/keycloak-admin-client/src/resources/agent.ts:273

      });

      // now we get the response of the http request
      // if `resourceIdInLocationHeader` is true, we'll get the resourceId from the location header field
      // todo: find a better way to find the id in path, maybe some kind of pattern matching
      // for now, we simply split the last sub-path of the path returned in location header field
      if (returnResourceIdInLocationHeader) {
        const locationHeader = res.headers.get("location");

        if (typeof locationHeader !== "string") {
          throw new Error(
            `location header is not found in request: ${res.url}`,
          );
        }

        const resourceId = locationHeader.split(SLASH).pop();
        if (!resourceId) {
          // throw an error to let users know the response is not expected
          throw new Error(
            `resourceId is not found in Location header from request: ${res.url}`,
          );
        }

        // return with format {[field]: string}
        const { field } = returnResourceIdInLocationHeader;
        return { [field]: resourceId };
      }

      if (
        Object.entries(headers || []).find(
          ([key, value]) =>
            key.toLowerCase() === "accept" &&
            value === "application/octet-stream",
        )
      ) {
        return await res.arrayBuffer();
      }

View on GitHub (pinned to 66c7e15a37)

Solutions

  1. Log the raw `location` header value to see its exact shape.
  2. If the server appends a trailing slash, normalise/proxy-fix so the Location ends with the new id.
  3. Avoid `returnResourceIdInLocationHeader` for that resource and read the id from the response body if available.
  4. Report the malformed Location to the backend/proxy owner if it is a regression.

Example fix

// before
return { [field]: locationHeader.split(SLASH).pop() };

// after: tolerate trailing slashes
const trimmed = locationHeader.replace(/\/+$/, '');
const resourceId = trimmed.split(SLASH).pop();
Defensive patterns

Strategy: validation

Validate before calling

function extractResourceId(location: string): string | undefined {
  const trimmed = location.replace(/\/+$/, '');
  const id = trimmed.split('/').pop();
  return id || undefined;
}

Type guard

const locationHasTrailingId = (location: string): boolean =>
  Boolean(location.replace(/\/+$/, '').split('/').pop());

Try / catch

try {
  const { id } = await kcAdminClient.clients.create({ ...payload });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('resourceId is not found in Location header')) {
    // Location malformed; fall back to listing/lookup
  } else throw e;
}

Prevention

When it happens

Trigger: The `Location` header is `https://host/realms/master/clients/` (trailing slash), a bare `https://host/`, or otherwise ends in a delimiter; the header points somewhere the naive `split('/').pop()` heuristic cannot parse.

Common situations: Server or proxy normalises URLs and appends a trailing slash; the Location is an external/absolute URL whose last path segment is empty; a routing layer rewrites the Location value.

Related errors


AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14). Data as JSON: /api/errors/647a6b256b695e9d. Report an issue: GitHub.