If you’re working with Retrofit in Kotlin and encounter the error Expected BEGIN_OBJECT but was BEGIN_ARRAY
, it usually means that your app expects a JSON object but receives a JSON array instead. This mismatch typically occurs due to incorrect data modeling. Here’s how you can solve it by adjusting your model and interface definitions correctly.

Understanding the Error
The error message:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
means Retrofit is trying to parse a JSON response that starts with [
(an array), but your Kotlin model expects a JSON object {
.
Step-by-Step Solution
1. Inspect Your API Response
Before coding, visit your API endpoint using Postman or cURL and check the structure of the JSON response. If it looks like this:
[ { "id": 1, "name": "Product A" }, { "id": 2, "name": "Product B" } ]
Then it’s a JSON array and your model should reflect that.
2. Create the Correct Data Model
Instead of modeling a single object, define a list of data classes:
Product.kt
data class Product( val id: Int, val name: String )
3. Define the Retrofit Interface Correctly
If the API returns an array of products, you must define your response type as a list:
ApiService.kt
import retrofit2.Call import retrofit2.http.GET interface ApiService { @GET("products") fun getProducts(): Call<List<Product>> }
4. Create the Retrofit Instance
RetrofitClient.kt
import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory object RetrofitClient { private const val BASE_URL = "https://yourapi.com/api/" val instance: ApiService by lazy { val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() retrofit.create(ApiService::class.java) } }
5. Consume the API in Your ViewModel or Activity
MainActivity.kt
import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import retrofit2.Call import retrofit2.Callback import retrofit2.Response class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) RetrofitClient.instance.getProducts().enqueue(object : Callback<List<Product>> { override fun onResponse(call: Call<List<Product>>, response: Response<List<Product>>) { if (response.isSuccessful) { response.body()?.let { products -> for (product in products) { Log.d("MainActivity", "Product: ${product.name}") } } } } override fun onFailure(call: Call<List<Product>>, t: Throwable) { Log.e("MainActivity", "Error: ${t.message}") } }) } }
Final Thoughts
To avoid Expected BEGIN_OBJECT but was BEGIN_ARRAY
, always confirm the actual API response structure before modeling your data. If you’re consuming third-party APIs, use tools like jsonschema2pojo to auto-generate correct Kotlin/Java models based on the JSON response.