{"record":{"id":"727595d937399a4f","repo":"keycloak/keycloak","slug":"location-header-is-not-found-in-request-res-url","errorCode":null,"errorMessage":"location header is not found in request: ${res.url}","messagePattern":"location header is not found in request: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/libs/keycloak-admin-client/src/resources/agent.ts","lineNumber":265,"sourceCode":"    try {\n      const res = await fetchWithError(url, {\n        ...requestOptions,\n        headers: requestHeaders,\n        method,\n        ...(this.#client.timeout\n          ? { signal: AbortSignal.timeout(this.#client.timeout) }\n          : {}),\n      });\n\n      // now we get the response of the http request\n      // if `resourceIdInLocationHeader` is true, we'll get the resourceId from the location header field\n      // todo: find a better way to find the id in path, maybe some kind of pattern matching\n      // for now, we simply split the last sub-path of the path returned in location header field\n      if (returnResourceIdInLocationHeader) {\n        const locationHeader = res.headers.get(\"location\");\n\n        if (typeof locationHeader !== \"string\") {\n          throw new Error(\n            `location header is not found in request: ${res.url}`,\n          );\n        }\n\n        const resourceId = locationHeader.split(SLASH).pop();\n        if (!resourceId) {\n          // throw an error to let users know the response is not expected\n          throw new Error(\n            `resourceId is not found in Location header from request: ${res.url}`,\n          );\n        }\n\n        // return with format {[field]: string}\n        const { field } = returnResourceIdInLocationHeader;\n        return { [field]: resourceId };\n      }\n\n      if (","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/keycloak/keycloak/blob/66c7e15a3788de7764f07dd2558275a02770e16d/js/libs/keycloak-admin-client/src/resources/agent.ts#L247-L283","documentation":"Thrown by the admin-client request `agent` when a request was made with the `returnResourceIdInLocationHeader` option (used for create operations that return the new resource's id in the `Location` response header) but the response carries no `location` header. The agent specifically needs that header to extract the id, so it aborts.","triggerScenarios":"A `.create()`/`.post()` call where the server returned 2xx but omitted the `Location` header; a reverse proxy stripped the `Location` header; the operation does not actually return a `Location` header but the option was set; the server used a different header casing that the Headers API normalises away but the value was absent.","commonSituations":"Calling a non-standard endpoint that signals the new id in the body instead of the header; a proxy/load-balancer dropping `Location`; Keycloak version changed the create response shape for a resource.","solutions":["Inspect the full response headers (and body) to confirm whether the server emitted a `Location` at all.","If the proxy is stripping it, configure the proxy to pass `Location` through.","If the endpoint returns the id in the body, do not set `returnResourceIdInLocationHeader` and parse the body instead.","Verify the resource genuinely supports Location-based id return for that Keycloak version."],"exampleFix":"// before\nconst { id } = await kcAdminClient.clients.create({ ... });\n\n// after: the resource returns the id in the body\nconst created = await kcAdminClient.someResource.create({\n  ...payload,\n  // returnResourceIdInLocationHeader removed / not set\n});\nconst id = created.id;","handlingStrategy":"validation","validationCode":"const res = await fetch(url, opts);\nconst location = res.headers.get('location');\nif (returnResourceIdInLocationHeader && typeof location !== 'string') {\n  // endpoint does not return Location; do not request id-from-location\n  throw new Error(`Endpoint ${res.url} does not return a Location header; disable returnResourceIdInLocationHeader.`);\n}","typeGuard":"const hasLocationHeader = (res: Response): boolean =>\n  typeof res.headers.get('location') === 'string';","tryCatchPattern":"try {\n  const { id } = await kcAdminClient.clients.create({ ...payload });\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('location header is not found')) {\n    // resource returns id in body instead\n    const created = await kcAdminClient.clients.findOne(...);\n  } else throw e;\n}","preventionTips":["Confirm the endpoint actually emits a Location header before enabling returnResourceIdInLocationHeader.","Ensure proxies pass the Location header through.","Prefer reading the id from the response body when available."],"tags":["network","http","headers","admin-client","create"],"backgroundTag":null,"analyzedSha":"66c7e15a3788de7764f07dd2558275a02770e16d","analyzedAt":"2026-08-14T01:36:42.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}