{"record":{"id":"844ced32410d3338","repo":"Budibase/budibase","slug":"cloudfront-private-key-64-is-not-set","errorCode":null,"errorMessage":"CLOUDFRONT_PRIVATE_KEY_64 is not set","messagePattern":"CLOUDFRONT_PRIVATE_KEY_64 is not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/objectStore/cloudfront.ts","lineNumber":8,"sourceCode":"import env from \"../environment\"\nimport * as cfsign from \"aws-cloudfront-sign\"\n\nlet PRIVATE_KEY: string | undefined\n\nfunction getPrivateKey() {\n  if (!env.CLOUDFRONT_PRIVATE_KEY_64) {\n    throw new Error(\"CLOUDFRONT_PRIVATE_KEY_64 is not set\")\n  }\n\n  if (PRIVATE_KEY) {\n    return PRIVATE_KEY\n  }\n\n  PRIVATE_KEY = Buffer.from(env.CLOUDFRONT_PRIVATE_KEY_64, \"base64\").toString(\n    \"utf-8\"\n  )\n\n  return PRIVATE_KEY\n}\n\nconst getCloudfrontSignParams = () => {\n  return {\n    keypairId: env.CLOUDFRONT_PUBLIC_KEY_ID!,\n    privateKeyString: getPrivateKey(),\n    expireTime: new Date().getTime() + 1000 * 60 * 60 * 24, // 1 day","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/objectStore/cloudfront.ts#L1-L26","documentation":"cloudfront.ts signs CloudFront URLs using a private key that must be supplied base64-encoded in the CLOUDFRONT_PRIVATE_KEY_64 environment variable. getPrivateKey throws this error when that env var is unset. Without the key, no CloudFront URL can be signed.","triggerScenarios":"Any call chain reaching getCloudfrontSignParams (e.g. generating signed URLs for object store assets) while CLOUDFRONT_PRIVATE_KEY_64 is missing from the environment.","commonSituations":"Self-hosted deployment using CloudFront object store without setting the env var; key set in one service (server) but not another (worker); docker-compose/.env file missing the variable; variable set after process start without restart.","solutions":["Set CLOUDFRONT_PRIVATE_KEY_64 to the base64-encoded CloudFront private key (.pem contents) in the environment of the failing service","Restart the server/worker processes so the new env var is picked up","Verify with the CloudFront key pair: the key must match the CLOUDFRONT key pair ID configured for the distribution","If not using CloudFront, correct the object store configuration so the CloudFront signing path is not taken"],"exampleFix":"// before (.env)\n# CLOUDFRONT_PRIVATE_KEY_64 not set\n// after (.env)\nCLOUDFRONT_PRIVATE_KEY_64=$(base64 -w0 pk-APXXXXXXXX.pem)","handlingStrategy":"validation","validationCode":"if (!process.env.CLOUDFRONT_PRIVATE_KEY_64) {\n  throw new Error(\"Set CLOUDFRONT_PRIVATE_KEY_64 (base64 of the CloudFront .pem) before starting\")\n}\nconst decoded = Buffer.from(process.env.CLOUDFRONT_PRIVATE_KEY_64, \"base64\").toString()\nif (!decoded.includes(\"PRIVATE KEY\")) throw new Error(\"CLOUDFRONT_PRIVATE_KEY_64 does not decode to a PEM private key\")","typeGuard":"function hasCloudfrontKey(env): env is { CLOUDFRONT_PRIVATE_KEY_64: string } {\n  return typeof env.CLOUDFRONT_PRIVATE_KEY_64 === \"string\" && env.CLOUDFRONT_PRIVATE_KEY_64.length > 0\n}","tryCatchPattern":"try {\n  const signedUrl = await getSignedUrl(params)\n} catch (err) {\n  if (String(err.message) === \"CLOUDFRONT_PRIVATE_KEY_64 is not set\") {\n    // fail fast at startup instead: check the env var during boot and abort with clear instructions\n  }\n}","preventionTips":["Add a boot-time assertion that all required object-store env vars are present","Set the variable for every service that touches the object store (server, worker)","Base64-encode the full .pem file contents (including header/footer lines)","Restart services after changing .env — env vars are read at process start"],"tags":["configuration","environment","cloudfront","aws"],"backgroundTag":"missing-env-var","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}