POST Multipart Form Data using Retrofit 2.0 including image
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Uploading an image with form fields is a standard Android workflow for profiles, tickets, and content publishing. Retrofit 2 handles this cleanly with multipart requests, but small mistakes in request body creation often cause server errors. A robust setup includes correct MIME types, stable URI handling, and explicit endpoint contracts.
Defining the Retrofit API Contract
Start with a clear service interface. Use @Multipart and split binary and text parameters into separate parts.
This contract maps directly to a typical multipart form where one part is file data and other parts are text fields.
Creating Request Parts Correctly
On Android, you often start from a content Uri chosen in a picker. Convert it to a temporary file or stream safely, then build parts with accurate media types.
Hardcoding a wrong media type is a common cause of backend rejection. If file type can vary, derive MIME via ContentResolver and fallback conservatively.
Executing the Upload with Coroutines
Run network calls off the main thread using coroutines and expose structured success or failure to the UI layer.
This pattern keeps concerns separated: API contract, part creation, and use case flow.
Debugging Multipart Requests
If server parsing fails, inspect outgoing requests with an OkHttp logging interceptor or a proxy tool. Validate part names, not only values. Backend code usually expects exact field names such as image or avatar, and mismatch causes silent null values server side.
Also verify server limits. Large files can trigger 413 responses or framework-level exceptions before controller code runs.
Hardening the Upload Flow
Production apps need guardrails around the upload call. Validate local file size before network work starts, and fail fast with a clear message when the file is above server policy. Early validation saves battery and avoids long transfers that are guaranteed to fail.
Treat duplicate submission as a first-class case. Users often tap the action button multiple times during slow uploads. Disable the button while upload is in progress, or send an idempotency key so backend logic can collapse duplicate requests safely.
For reliability on unstable networks, separate media upload from profile metadata update. First upload the file and obtain a media id or URL. Then send metadata in a second call. That split gives cleaner retry boundaries and makes partial failure recovery much easier.
A small state model like this keeps the UI deterministic across retries, rotation, and process recreation.
Common Pitfalls
- Using wrong part names. Fix by matching backend field names exactly in
createFormDataand@Partkeys. - Sending file URI string instead of binary content. Fix by opening stream and creating
MultipartBody.Partfrom bytes. - Forgetting MIME type correctness. Fix by using detected media type and validating backend expectations.
- Running upload on main thread. Fix by executing in
Dispatchers.IO. - Ignoring non success responses. Fix by checking
isSuccessfuland parsing error payload for diagnostics.
Summary
- Use
@Multipartwith oneMultipartBody.Partfor image andRequestBodyfor text fields. - Convert content
Urito request body safely through streams. - Keep API contract and upload orchestration cleanly separated.
- Validate field names and MIME types first when debugging.
- Treat response codes and empty payloads as explicit failure paths.
Related reading
- Post parameter is always null
- POST request with a simple string in body with Alamofire
- Posting a File and Associated Data to a RESTful WebService preferably as JSON
- POSTing a OneToMany sub-resource association in Spring Data REST
- Posting a runnable to a View that invalidates the View sometimes doesn't work
- Posting NSNotification on the main thread
- Powershell v3 Invoke-WebRequest HTTPS error
- Preferred Java way to ping an HTTP URL for availability

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.