paperclipai/paperclip · error
Cloud runtime identity stack does not match this instance
Error message
Cloud runtime identity stack does not match this instance
What it means
verifyCloudRuntimeIdentityAssertion checks that the assertion's sub claim names the exact stack this instance belongs to (PAPERCLIP_CLOUD_STACK_ID). It throws when PAPERCLIP_CLOUD_STACK_ID is unset or when the assertion was minted for a different stack id, so a foreign runtime identity cannot claim this instance.
Source
Thrown at server/src/services/cloud-runtime-identity.ts:326
|| payload.exp - payload.iat > MAX_ASSERTION_LIFETIME_SECONDS
) {
throw new Error("Cloud runtime identity assertion is expired or has an invalid lifetime");
}
return payload as RuntimeIdentityClaims;
}
/** Verify that an assertion is signed for this exact, still-unclaimed instance. */
export function verifyCloudRuntimeIdentityAssertion(input: {
compactJws: string;
env?: NodeJS.ProcessEnv;
now?: Date;
expectedPreviousOrigin: string | null;
}): RuntimeIdentityClaims {
const env = input.env ?? process.env;
const claims = verifyClaims({ compactJws: input.compactJws, env, now: input.now ?? new Date() });
const configuredStackId = nonEmpty(env.PAPERCLIP_CLOUD_STACK_ID);
if (!configuredStackId || claims.sub !== configuredStackId) {
throw new Error("Cloud runtime identity stack does not match this instance");
}
const previousOrigin = exactHttpsOrigin(claims.previousOrigin);
const canonicalOrigin = exactHttpsOrigin(claims.canonicalOrigin);
if (!previousOrigin || !canonicalOrigin || previousOrigin !== input.expectedPreviousOrigin) {
throw new Error("Cloud runtime identity previous or canonical origin is invalid");
}
if (
!STACK_SLUG_PATTERN.test(claims.stackSlug)
|| new URL(canonicalOrigin).hostname.split(".")[0] !== claims.stackSlug
|| claims.claimId.length > 256
|| claims.claimId.trim() !== claims.claimId
|| !claims.claimId
) {
throw new Error("Cloud runtime identity destination is invalid");
}
return claims;
}
View on GitHub (pinned to 01ad858492)
Solutions
- Set PAPERCLIP_CLOUD_STACK_ID in the instance environment to the stack id the assertion was minted for
- Re-mint the assertion with sub equal to this instance's stack id
- Confirm the assertion delivery is targeting the correct instance/stack
- Log claims.sub (server-side) and compare against env to diagnose mismatch
Example fix
// before PAPERCLIP_CLOUD_STACK_ID= # unset // after PAPERCLIP_CLOUD_STACK_ID=stack_01hxyz # matches assertion sub claim
Defensive patterns
Strategy: validation
Validate before calling
const configured = process.env.PAPERCLIP_CLOUD_STACK_ID;
const sub = decodeJwtPayload(jws).sub;
if (!configured || sub !== configured) throw new Error(`stack mismatch: sub=${sub} configured=${configured}`); Type guard
function matchesStack(claims: {sub:string}, env: NodeJS.ProcessEnv): boolean {
return Boolean(env.PAPERCLIP_CLOUD_STACK_ID) && claims.sub === env.PAPERCLIP_CLOUD_STACK_ID;
} Try / catch
try {
await applyCloudRuntimeIdentityAssertion({ db, compactJws: jws });
} catch (e) {
if (e.message.includes('stack does not match')) {
logger.error({ configured: process.env.PAPERCLIP_CLOUD_STACK_ID }, 'assertion minted for a different stack');
}
throw e;
} Prevention
- Set PAPERCLIP_CLOUD_STACK_ID in every instance environment as part of provisioning
- Never copy assertions between stacks; mint per-stack
- Include stack id in deployment checks/health probes
- Keep assertion delivery channels stack-scoped
When it happens
Trigger: applyCloudRuntimeIdentityAssertion or verifyAssertion called where env.PAPERCLIP_CLOUD_STACK_ID is empty/nonEmpty-false, or where claims.sub differs from the configured stack id (e.g. assertion minted for stack A delivered to an instance of stack B).
Common situations: PAPERCLIP_CLOUD_STACK_ID not set in the instance environment; copy-pasting an assertion between dev/staging/prod stacks; re-pointing an instance to a new stack without re-minting the assertion; stale container images with old stack env.
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
- Cloud runtime identity previous or canonical origin is inval
- Cloud runtime identity destination is invalid
- Unknown config key ${warning.path}; did you mean ${warning.s
- Unknown config key ${warning.path}; did you mean ${warning.s
- "configJson" is required and must be an object
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/37c2f554350d9025.
Report an issue: GitHub.