You are bitten by argument decay.
Argument decay means that int arr[N] is fancy talk for int* arr.  The N is utterly ignored.
On top of that, arrfill<N-1> is a call to a template function whose first argument is a size_t (or compatible).  Your T arr[0] is an overload that takes as its first template argument a type.  So it cannot be selected.
To work around argument decay, you should take arrays by reference.
template<typename T>
bool arrfill(T (&arr)[1], T v){arr[0]=v;}
template<size_t N, typename T>
void arrfill(T (&arr)[N], T v){
  arr[0] = v;
  arrfill(*reinterpret_cast<T(*)[N-1]>(arr+1), v);
}
Sadly, this is undefined behavior; I am casting parts of an array into arrays of type it isn't.  This happens to be undefined behavior which every single C++ compiler I have ever used consumes and does "the right thing", but it is still undefined behavior.  And we should avoid that unless we have a strong reason not to; while clean and clear, clean code is not (in my opinion) a good reason to do UB.  UB can come back to bite us 10 years from now when compilers update, and I don't want to maintain this code every compiler update and ensure it still works.
So really, use packs and folding.
template<size_t N, typename T,std::size_t...Is>
void arrfill(T (&arr)[N], T v,std::index_sequence<Is...>){
  ((void)(arr[Is]=v),...);
}
template<size_t N, typename T>
void arrfill(T (&arr)[N], T v){
  arrfill(arr, v, std::make_index_sequence<N>{});
}
or just use std::fill_n.
template<size_t N, typename T>
void arrfill(T (&arr)[N], T v){
  std::fill_n( std::begin(arr), N, v );
}
if you really, really must use recursion
template<size_t N, typename T>
void arrfill(T* arr, T v){
  if constexpr(N==0) {
    return;
  } else {
    arr[0] = v;
    arrfill<N-1>(arr+1, v);
  }
}
does it.  In c++11 we can't use if constexpr.  So we do something else.
template<typename T>
void arrfill(std::integral_constant<std::size_t, 0>, T* arr, T const& v){
}
template<size_t N, typename T>
void arrfill(std::integral_constant<std::size_t, N>, T* arr, T const& v){
  arr[0] = v;
  arrfill(std::integral_constant<std::size_t, N-1>{}, arr+1, v);
}
template<size_t N, typename T>
void arrfill(T(&arr)[N], T const& v){
  arrFill(std::integral_constant<std::size_t, N>{}, arr, v);
}
this lets us select the 0 case using overloading.  We also deduce N automatically.