hcengineering/platform · error · DatalakeError

Failed to start multipart upload

Error message

Failed to start multipart upload

What it means

multipartUploadStart POSTs to initiate a multipart upload and wraps any failure (network, non-OK status, bad JSON) in a generic DatalakeError('Failed to start multipart upload') after logging the underlying error.

Solutions

  1. Inspect the logged underlying err for the root cause
  2. Verify datalake service availability and credentials
  3. Retry with backoff; check server version supports the multipart endpoint
Defensive patterns

Strategy: retry

Try / catch

try {
  const mp = await client.multipart(ctx, workspace, objectName, meta)
} catch (err) {
  if (err instanceof DatalakeError && err.message === 'Failed to start multipart upload') {
    // retry with exponential backoff; check service health if retries exhaust
  } else throw err
}

Prevention

When it happens

Trigger: POST to the multipart init endpoint fails: service unreachable, auth rejected, workspace/objectName invalid, or response not valid MultipartUpload JSON.

Common situations: Datalake service down or DNS/proxy issues; expired credentials; uploading very large files where multipart is used and the service doesn't support the multipart API version.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/dc7b57d5cde3cbc2. Report an issue: GitHub.

Appendix: source

Thrown at foundations/server/packages/datalake/src/client.ts:405

    workspace: WorkspaceUuid,
    objectName: string,
    params: UploadObjectParams
  ): Promise<MultipartUpload> {
    const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}`
    const url = concatLink(this.endpoint, path)

    try {
      const headers = {
        ...this.headers,
        'Content-Type': params.type,
        'Content-Length': params.size?.toString() ?? '0',
        'Last-Modified': new Date(params.lastModified).toUTCString()
      }
      const response = await fetchSafe(ctx, url, { method: 'POST', headers })
      return (await response.json()) as MultipartUpload
    } catch (err: any) {
      ctx.error('failed to start multipart upload', { workspace, objectName, err })
      throw new DatalakeError('Failed to start multipart upload')
    }
  }

  private async multipartUploadPart (
    ctx: MeasureContext,
    workspace: WorkspaceUuid,
    objectName: string,
    multipart: MultipartUpload,
    partNumber: number,
    data: Readable | Buffer | string
  ): Promise<MultipartUploadPart> {
    const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}/part`
    const url = new URL(concatLink(this.endpoint, path))
    url.searchParams.set('uploadId', multipart.uploadId)
    url.searchParams.set('partNumber', partNumber.toString())

    const body = data instanceof Readable ? (Readable.toWeb(data) as ReadableStream) : data

View on GitHub (pinned to 63e28dc964)