{"record":{"id":"5a44cfc44aad93df","repo":"n8n-io/n8n","slug":"failed-to-get-upload-url","errorCode":null,"errorMessage":"Failed to get upload URL","messagePattern":"Failed to get upload URL","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vendors/GoogleGemini/helpers/utils.ts","lineNumber":193,"sourceCode":"\tstream: Stream,\n\tconfig: UploadStreamConfig,\n): Promise<{ body: IDataObject }> {\n\tconst { endpoint, mimeType, body } = config;\n\n\tconst uploadInitResponse = (await apiRequest.call(this, 'POST', endpoint, {\n\t\theaders: {\n\t\t\t'X-Goog-Upload-Protocol': 'resumable',\n\t\t\t'X-Goog-Upload-Command': 'start',\n\t\t\t'X-Goog-Upload-Header-Content-Type': mimeType,\n\t\t\t'Content-Type': 'application/json',\n\t\t},\n\t\tbody,\n\t\toption: { returnFullResponse: true },\n\t})) as { headers: IDataObject };\n\n\tconst uploadUrl = uploadInitResponse.headers['x-goog-upload-url'] as string;\n\tif (!uploadUrl) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Failed to get upload URL');\n\t}\n\n\treturn (await this.helpers.httpRequest({\n\t\tmethod: 'POST',\n\t\turl: uploadUrl,\n\t\theaders: {\n\t\t\t'X-Goog-Upload-Offset': '0',\n\t\t\t'X-Goog-Upload-Command': 'upload, finalize',\n\t\t\t'Content-Type': mimeType,\n\t\t},\n\t\tbody: stream,\n\t\treturnFullResponse: true,\n\t})) as { body: IDataObject };\n}\n\nexport async function transferFile(\n\tthis: IExecuteFunctions,\n\ti: number,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vendors/GoogleGemini/helpers/utils.ts#L175-L211","documentation":"Failure in uploadStream's resumable-upload init: after POSTing to the endpoint with X-Goog-Upload-Protocol: resumable / Command: start, Google is expected to return an 'x-goog-upload-url' response header. If that header is absent, the node cannot proceed to the byte-upload phase and throws this bare message (no description attached).","triggerScenarios":"Google's resumable-upload start endpoint responded without issuing an upload URL — typically a 4xx/5xx that wasn't surfaced as a thrown HTTP error earlier (e.g. auth still valid enough to get a 200 with an error body), or a region/project where the Files API is unavailable, or a malformed body/mimeType.","commonSituations":"API key / OAuth scope lacks the cloudplatform or generativelanguage scope; the project hasn't enabled the Generative Language API; transient Google-side issue; mimeType header empty causing Google to refuse the start.","solutions":["Verify the Google API credential has the required scopes and that 'Generative Language API' is enabled in the Google Cloud project.","Retry — a missing upload URL is frequently transient on Google's side.","Check the apiRequest call earlier didn't silently swallow a non-2xx; if you can, capture the start response status/body to see Google's reason.","Confirm mimeType is a non-empty, valid MIME string before this call."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function hasUploadUrl(headers: Record<string, unknown>): boolean {\n  return typeof headers['x-goog-upload-url'] === 'string' && (headers['x-goog-upload-url'] as string).length > 0;\n}","tryCatchPattern":"for (let attempt = 1; attempt <= 3; attempt++) {\n  try { return await uploadStream(stream, config); }\n  catch (e) {\n    if (attempt === 3 || !/upload url/i.test(e.message)) throw e;\n    await new Promise(r => setTimeout(r, 1000 * attempt));\n  }\n}","preventionTips":["Ensure the credential has the Generative Language / Cloud Platform scope before relying on resumable uploads.","Confirm mimeType is a non-empty, valid MIME string — empty mimeType can make Google refuse the start command.","Retry on a missing upload URL — it's frequently transient."],"tags":["google-gemini","file-upload","resumable-upload","api-error","headers","node-operation-error"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}