Can you not leave the created_at field out of the query alltogether and instead, orderby('month')?
From a pure SQL side of things, you're trying to group things together but also showing the detail (i.e. group by month, but select individual dates too) which is why you're getting those results
// Returns 2018-09-01 00:00:00
$start = Carbon::createMidnightDate(Carbon::now()->subMonths(8)->year, 9, 1);
// Gets current date
$end = Carbon::now();
$users = DB::table('concerns')
->select(DB::raw('MONTHNAME(created_at) as month, count(*) as total'))
->whereBetween('created_at', [$start, $end])
->groupBy('month')
->orderBy('month'_at', 'asc')
->get()->mapWithKeys(function ($item) {
return [$item->month => $item->total];
});