{"record":{"id":"e7525886d7997b3d","repo":"HeyPuter/puter","slug":"internal-error-e75258","errorCode":"internal_error","errorMessage":"Server misconfiguration: url_signature_secret not set","messagePattern":"Server misconfiguration: url_signature_secret not set","errorType":"http","errorClass":"HttpError","httpStatus":500,"severity":"critical","filePath":"src/backend/controllers/fs/legacyFsHelpers.ts","lineNumber":507,"sourceCode":"        response.thumbnail as string | null,\n    );\n\n    return response;\n}\n\nexport { normalizeAbsolutePath };\n\n// -- Signing ---------------------------------------------------------\n\n/**\n * Pull the signing config off the app config. Throws if either value is missing\n * — these are required for signed URL routes to function.\n */\nexport function signingConfigFromAppConfig(config: IConfig): SigningConfig {\n    const secret = config.url_signature_secret;\n    const apiBaseUrl = config.api_base_url;\n    if (typeof secret !== 'string' || secret.length === 0) {\n        throw new HttpError(\n            500,\n            'Server misconfiguration: url_signature_secret not set',\n            { legacyCode: 'internal_error' },\n        );\n    }\n    if (typeof apiBaseUrl !== 'string' || apiBaseUrl.length === 0) {\n        throw new HttpError(\n            500,\n            'Server misconfiguration: api_base_url not set',\n            { legacyCode: 'internal_error' },\n        );\n    }\n    return { secret, apiBaseUrl };\n}\n\n/** Convenience wrapper: turn an FSEntry into a signed-file response object. */\nexport function signEntry(\n    entry: {","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/fs/legacyFsHelpers.ts#L489-L525","documentation":"The server requires a `url_signature_secret` config value to HMAC-sign file download URLs. `signingConfigFromAppConfig()` throws HTTP 500 when the key is absent, not a string, or empty — it is a deployment defect, not a client error. Every signed-URL route (file read, stat, thumbnail) is unusable until the secret is set.","triggerScenarios":"Any request path that produces a signed file URL calls `signingConfigFromAppConfig(config)`. If `config.url_signature_secret` is unset/empty/non-string, the call throws before a URL can be built. Triggered by file-stat, file-read, and thumbnail responses that include signed download links.","commonSituations":"Self-hosting Puter from a config template with the signing secret left blank; rotating secrets and forgetting to repopulate the field; loading the wrong config file (e.g., dev config in production) that omits the key.","solutions":["Set `url_signature_secret` to a cryptographically random string of at least 32 bytes in your active config.json (or the corresponding env var).","Generate a secret with `node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"` and paste it into config.","Restart the backend process so the new config is loaded.","Verify by issuing a file-stat request and confirming the returned download URL includes a `signature` query parameter."],"exampleFix":"// before (config.json)\n{\n  \"api_base_url\": \"https://api.example.com\"\n  // url_signature_secret missing\n}\n\n// after\n{\n  \"api_base_url\": \"https://api.example.com\",\n  \"url_signature_secret\": \"<64-char hex random string>\"\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Client cannot prevent this — it is a server config error.\n// Catch and surface to the user / ops team.\ntry {\n  const res = await fetch('/api/drivers/call', { /* ... */ });\n  if (!res.ok) throw await res.json();\n} catch (e) {\n  if (e.message?.includes('url_signature_secret')) {\n    console.error('Server is misconfigured. Contact the administrator.');\n  }\n}","preventionTips":["Self-hosters: run a config validation script on startup that asserts all required keys are present.","Include `url_signature_secret` in your deployment checklist and config templates.","Add a health-check endpoint that verifies signing config at boot and fails loudly if missing."],"tags":["config","security","self-hosting","signed-urls","http-500"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}