paperclipai/paperclip · error

cloud_runtime_identity_wrong_endpoint

cloud_runtime_identity_wrong_endpoint

Error message

cloud_runtime_identity_wrong_endpoint

What it means

The cloud runtime identity middleware only accepts identity assertions on GET /api/health. When a request carries the Cloud runtime identity header but targets any other method or path, the middleware rejects it with HTTP 400 and this code before any downstream handling. The assertion is meant to be presented once at the health probe to establish runtime identity, so presenting it elsewhere indicates a misconfigured client or probe.

Source

Thrown at server/src/middleware/cloud-runtime-identity.ts:22

import {
  applyCloudRuntimeIdentityAssertion,
  CLOUD_RUNTIME_IDENTITY_HEADER,
} from "../services/cloud-runtime-identity.js";

/**
 * Accepts Cloud's signed identity only on the existing bootstrap health call.
 * The JWS is sufficient authorization; the browser-facing proxy strips this
 * header, and possession of the shared tenant-session token cannot mint it.
 */
export function cloudRuntimeIdentityMiddleware(db: Db): RequestHandler {
  return async (req, res, next) => {
    const assertion = req.get(CLOUD_RUNTIME_IDENTITY_HEADER)?.trim();
    if (!assertion) {
      next();
      return;
    }
    if (req.method !== "GET" || req.path !== "/api/health") {
      res.status(400).json({ error: "cloud_runtime_identity_wrong_endpoint" });
      return;
    }
    try {
      await applyCloudRuntimeIdentityAssertion({ db, compactJws: assertion });
      next();
    } catch (error) {
      logger.warn({ err: error }, "Rejected Cloud runtime identity assertion");
      res.status(401).json({ error: "invalid_cloud_runtime_identity" });
    }
  };
}

View on GitHub (pinned to 01ad858492)

Solutions

  1. Remove the cloud runtime identity header from all requests except GET /api/health; configure the injecting proxy/sidecar to attach it only on the health path
  2. If your probe framework requires the header on other endpoints, change the probe URL to /api/health with method GET
  3. Check the client/proxy config (e.g. health-check header injection rules) and scope it to path /api/health
  4. If you believe the header is needed elsewhere, revisit the middleware gating condition and update intentionally, not ad hoc

Example fix

// before (client injects header on every request)
http.get('/api/companies', { headers: { 'x-cloud-runtime-identity': token } });
// after
http.get('/api/health', { headers: { 'x-cloud-runtime-identity': token } });
Defensive patterns

Strategy: validation

Validate before calling

if (assertionHeader && !(method === 'GET' && path === '/api/health')) { throw new Error('cloud runtime identity assertion is only valid on GET /api/health'); }

Type guard

function isHealthIdentityRequest(req: { method: string; path: string }) { return req.method === 'GET' && req.path === '/api/health'; }

Try / catch

null

Prevention

When it happens

Trigger: A request includes the CLOUD_RUNTIME_IDENTITY_HEADER header with a non-empty trimmed assertion, but req.method !== 'GET' or req.path !== '/api/health'. Typical causes: the identity sidecar or proxy injects the assertion header into every request instead of only the health check, or a client sends the header on POST/PUT business endpoints.

Common situations: Operators configure a service mesh or load balancer to attach the runtime identity header globally rather than on health probes; clients hardcode the header into default HTTP clients; after a middleware update, previously accepted header-on-all-routes behavior becomes a 400.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/f241421712e6f571. Report an issue: GitHub.