Skip to content

RepositoryFileApi fails to upload large files (10MB+) due to application/x-www-form-urlencoded encoding #1276

@heyuqiang

Description

@heyuqiang

Description

When using RepositoryFileApi.createFile() or updateFile() in GitLab4J to upload a Base64-encoded file (~10MB ZIP), the request fails with HTTP 400.

Directly calling the GitLab API via curl with Content-Type: application/json works correctly.

Steps to Reproduce

Prepare a ZIP file test.zip (~10MB).

Use GitLab4J RepositoryFileApi to upload it as Base64 content:

RepositoryFile file = new RepositoryFile();
file.setFilePath("test.zip");
file.setContent(base64Content);
file.setEncoding(org.gitlab4j.models.Constants.Encoding.BASE64);

RepositoryFileApi fileApi = gitLabApi.getRepositoryFileApi();
fileApi.createFile(projectId, file, "main", "add test.zip");

The API returns HTTP 400 Bad Request.

The server logs show (Rails / Workhorse):

{
"status":400,
"written_bytes":11,
"method":"PUT",
"uri":"/api/v4/projects/2/repository/files/test.zip",
"backend_id":"rails"
}

Using curl works:

curl --request POST
--header "PRIVATE-TOKEN: $TOKEN"
--header "Content-Type: application/json"
--data '{
"branch": "main",
"commit_message": "add test.zip",
"content": "",
"encoding": "base64"
}'
"$GITLAB_URL/api/v4/projects/$PROJECT_ID/repository/files/test.zip"

Analysis

The GitLab4J post(Form formData, URL url) method sends the request as:

Entity.entity(formData.asMap(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)

That is, the request uses application/x-www-form-urlencoded instead of application/json.

For large Base64 files, Rails cannot parse the form-encoded body → 400.

Small text files may succeed, which is why this only occurs for large files.

Expected Behavior

RepositoryFileApi should correctly upload large Base64 files (>10MB) using JSON requests.

Or GitLab4J should document the limitation and recommend using Project Upload API for large binary files.

Environment

GitLab4J version: 6.1.0

GitLab server version: gitlab-ce 18.3.0

Java version: jdk21

Suggested Solutions

Change RepositoryFileApi to send JSON with Content-Type: application/json.

Alternatively, clearly document that large binary files should use ProjectApi.uploadFile().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions