RepositoryFileApi fails to upload large files (10MB+) due to application/x-www-form-urlencoded encoding
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": "<BASE64>",
"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().
CommitPayload payload = new CommitPayload(); payload.setBranch("main"); payload.setCommitMessage("add dict1j.zip"); CommitAction action= new CommitAction(); action.setAction(CommitAction.Action.CREATE); action.setFilePath("dict1j.zip"); action.setContent(content); action.setEncoding(Constants.Encoding.BASE64); payload.withAction(action);
Commit commit = gitLabApi.getCommitsApi().createCommit(28, payload); System.out.println(commit.toString());